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  // CCA-PD < RX power < CCA-ED
680  rxPowerDbm = -70;
681 
682  // CASE 7: send one packet and check PHY state:
683  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
684  // otherwise it should be IDLE.
685 
686  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
687  // At 4us, STA PHY STATE should move from IDLE to RX
690  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
693  // Packet should have been successfully received
694  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 2);
695 
696  // CASE 8: send two packets with same power within the 4us window and check PHY state:
697  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
698  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
699 
700  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
701  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
702  // At 4us, STA PHY STATE should stay in IDLE
704  // 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
705  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 2);
706 
707  // CASE 9: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
708  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
709  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
710 
711  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
712  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
713  // At 4us, STA PHY STATE should stay in IDLE
715  // 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
716  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 2);
717 
718  // CASE 10: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
719  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
720  // but payload reception should fail (SNR too low to decode the modulation).
721 
722  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
723  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
724  // At 4us, STA PHY STATE should move from IDLE to RX
727  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
730  // In this case, the first packet should be marked as a failure
731  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 3);
732 
733  // CASE 11: send two packets with second one 3 dB higher within the 4us window and check PHY state:
734  // PHY preamble detection should switch because a higher packet is received within the 4us window,
735  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
736  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
737 
738  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
739  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
740  // At 4us, STA PHY STATE should stay in IDLE
742  // At 6us, STA PHY STATE should stay in IDLE
744  // 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
745  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 3);
746 
747  // CASE 12: send two packets with second one 6 dB higher within the 4us window and check PHY state:
748  // PHY preamble detection should switch because a higher packet is received within the 4us window,
749  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
750  // Payload reception should fail (SNR too low to decode the modulation).
751 
752  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
753  Simulator::Schedule (Seconds (12.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
754  // At 4us, STA PHY STATE should stay in IDLE
756  // At 6us, STA PHY STATE should move from IDLE to RX
759  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
762  // In this case, the second packet should be marked as a failure
763  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
764 
765  Simulator::Run ();
766  Simulator::Destroy ();
767 }
768 
776 {
777 public:
779  virtual ~TestSimpleFrameCaptureModel ();
780 
781 protected:
782  virtual void DoSetup (void);
783 
784 private:
785  virtual void DoRun (void);
786 
790  void Reset (void);
796  void SendPacket (double rxPowerDbm, uint32_t packetSize);
804  void RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
811 
814  void Expect1000BPacketDropped ();
815  void Expect1500BPacketDropped ();
816 
818 
823 };
824 
826 : TestCase ("Simple frame capture model test"),
827  m_rxSuccess1000B (false),
828  m_rxSuccess1500B (false),
829  m_rxDropped1000B (false),
830  m_rxDropped1500B (false)
831 {
832 }
833 
834 void
836 {
837  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
838 
839  Ptr<Packet> pkt = Create<Packet> (packetSize);
840  WifiMacHeader hdr;
841  WifiMacTrailer trailer;
842 
843  hdr.SetType (WIFI_MAC_QOSDATA);
844  hdr.SetQosTid (0);
845  uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize ();
846  Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency ());
847  hdr.SetDuration (txDuration);
848 
849  pkt->AddHeader (hdr);
850  pkt->AddTrailer (trailer);
851 
852  HeSigHeader heSig;
853  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
854  heSig.SetBssColor (txVector.GetBssColor ());
855  heSig.SetChannelWidth (txVector.GetChannelWidth ());
856  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
857  pkt->AddHeader (heSig);
858 
859  LSigHeader sig;
860  pkt->AddHeader (sig);
861 
862  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
863  pkt->AddPacketTag (tag);
864 
865  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
866  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
867  txParams->psd = txPowerSpectrum;
868  txParams->txPhy = 0;
869  txParams->duration = txDuration;
870  txParams->packet = pkt;
871 
872  m_phy->StartRx (txParams);
873 }
874 
875 void
876 TestSimpleFrameCaptureModel::RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
877 {
878  NS_LOG_FUNCTION (this << p << snr << txVector);
879  if (p->GetSize () == 1030)
880  {
881  m_rxSuccess1000B = true;
882  }
883  else if (p->GetSize () == 1530)
884  {
885  m_rxSuccess1500B = true;
886  }
887 }
888 
889 void
891 {
892  NS_LOG_FUNCTION (this << p << reason);
893  if (p->GetSize () == 1030)
894  {
895  m_rxDropped1000B = true;
896  }
897  else if (p->GetSize () == 1530)
898  {
899  m_rxDropped1500B = true;
900  }
901 }
902 
903 void
905 {
906  m_rxSuccess1000B = false;
907  m_rxSuccess1500B = false;
908  m_rxDropped1000B = false;
909  m_rxDropped1500B = false;
910 }
911 
912 void
914 {
915  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
916 }
917 
918 void
920 {
921  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
922 }
923 void
925 {
926  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
927 }
928 
929 void
931 {
932  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
933 }
934 
936 {
937  m_phy = 0;
938 }
939 
940 void
942 {
943  m_phy = CreateObject<SpectrumWifiPhy> ();
945  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
946  m_phy->SetErrorRateModel (error);
949 
952 
953  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
954  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
955  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
956 
957  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
958  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
959  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
960  m_phy->SetFrameCaptureModel (frameCaptureModel);
961 }
962 
963 void
965 {
966  RngSeedManager::SetSeed (1);
967  RngSeedManager::SetRun (1);
968  int64_t streamNumber = 2;
969  double rxPowerDbm = -30;
970  m_phy->AssignStreams (streamNumber);
971 
972  // CASE 1: send two packets with same power within the capture window:
973  // PHY should not switch reception because they have same power.
974 
975  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
976  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
977  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
978  Reset ();
979 
980  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
981  // PHY should not switch reception because first one has higher power.
982 
983  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
984  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
985  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
986  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
987  Reset ();
988 
989  // CASE 3: send two packets with second one 6 dB higher within the capture window:
990  // PHY should switch reception because the second one has a higher power.
991 
992  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
993  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
994  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
995  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
996  Reset ();
997 
998  // CASE 4: send two packets with second one 6 dB higher after the capture window:
999  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1000 
1001  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1002  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1003  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1004  Reset ();
1005 
1006  Simulator::Run ();
1007  Simulator::Destroy ();
1008 }
1009 
1017 {
1018 public:
1020  virtual ~TestPhyHeadersReception ();
1021 
1022 protected:
1023  virtual void DoSetup (void);
1025 
1029  void SendPacket (double rxPowerDbm);
1030 
1031 private:
1032  virtual void DoRun (void);
1033 
1038  void CheckPhyState (WifiPhyState expectedState);
1039  void DoCheckPhyState (WifiPhyState expectedState);
1040 };
1041 
1043 : TestCase ("PHY headers reception test")
1044 {
1045 }
1046 
1047 void
1049 {
1050  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
1051  MpduType mpdutype = NORMAL_MPDU;
1052 
1053  Ptr<Packet> pkt = Create<Packet> (1000);
1054  WifiMacHeader hdr;
1055  WifiMacTrailer trailer;
1056 
1057  hdr.SetType (WIFI_MAC_QOSDATA);
1058  hdr.SetQosTid (0);
1059  uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize ();
1060  Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency (), mpdutype, 0);
1061  hdr.SetDuration (txDuration);
1062 
1063  pkt->AddHeader (hdr);
1064  pkt->AddTrailer (trailer);
1065 
1066  HeSigHeader heSig;
1067  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
1068  heSig.SetBssColor (txVector.GetBssColor ());
1069  heSig.SetChannelWidth (txVector.GetChannelWidth ());
1070  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
1071  pkt->AddHeader (heSig);
1072 
1073  LSigHeader sig;
1074  pkt->AddHeader (sig);
1075 
1076  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
1077  pkt->AddPacketTag (tag);
1078 
1079  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1080  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1081  txParams->psd = txPowerSpectrum;
1082  txParams->txPhy = 0;
1083  txParams->duration = txDuration;
1084  txParams->packet = pkt;
1085 
1086  m_phy->StartRx (txParams);
1087 }
1088 
1089 void
1091 {
1092  //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
1093  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1094 }
1095 
1096 void
1098 {
1099  WifiPhyState currentState;
1100  PointerValue ptr;
1101  m_phy->GetAttribute ("State", ptr);
1102  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1103  currentState = state->GetState ();
1104  NS_LOG_FUNCTION (this << currentState);
1105  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1106 }
1107 
1108 
1110 {
1111  m_phy = 0;
1112 }
1113 
1114 void
1116 {
1117  m_phy = CreateObject<SpectrumWifiPhy> ();
1119  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1120  m_phy->SetErrorRateModel (error);
1123 }
1124 
1125 void
1127 {
1128  RngSeedManager::SetSeed (1);
1129  RngSeedManager::SetRun (1);
1130  int64_t streamNumber = 0;
1131  m_phy->AssignStreams (streamNumber);
1132 
1133  // RX power > CCA-ED
1134  double rxPowerDbm = -50;
1135 
1136  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1137  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1138 
1139  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1140  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1141  // At 10 us, STA PHY STATE should be RX.
1142  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1143  // 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.
1144  Simulator::Schedule (Seconds (1.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1145  Simulator::Schedule (Seconds (1.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1146  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1147  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1148  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1149 
1150  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1151  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1152 
1153  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1154  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1155  // At 10 us, STA PHY STATE should be RX.
1156  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1157  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1158  Simulator::Schedule (Seconds (2.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1159  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1160  // 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.
1161  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1162  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1163  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1164  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1165 
1166  // 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:
1167  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1168 
1169  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1170  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1171  // At 44 us (end of HE-SIG), STA PHY STATE should be RX (even though reception of HE-SIG failed)
1172  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1173  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1174  // 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.
1175  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1176  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1177  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1178  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1179 
1180  // 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:
1181  // PHY header reception should succeed.
1182 
1183  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1184  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1185  // At 44 us (end of HE-SIG), STA PHY STATE should be RX.
1186  Simulator::Schedule (Seconds (4.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1187  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1188  // 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.
1189  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1190  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1191  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1192  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1193 
1194  // RX power < CCA-ED
1195  rxPowerDbm = -70;
1196 
1197  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1198  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1199 
1200  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1201  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1202  // At 10 us, STA PHY STATE should be RX.
1203  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1204  // 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.
1205  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1206  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1207 
1208  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1209  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1210 
1211  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1212  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1213  // At 10 us, STA PHY STATE should be RX.
1214  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1215  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1216  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1217  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1218  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1219  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1220 
1221  // 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:
1222  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1223 
1224  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1225  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1226  // At 44 us (end of HE-SIG), STA PHY STATE should be RX (even though reception of HE-SIG failed).
1227  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1228  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1229  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1230  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1231 
1232  // 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:
1233  // PHY header reception should succeed.
1234 
1235  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1236  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1237  // At 44 us (end of HE-SIG), STA PHY STATE should be RX.
1238  Simulator::Schedule (Seconds (8.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1239  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1240  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1241  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1242 
1243  Simulator::Run ();
1244  Simulator::Destroy ();
1245 }
1246 
1254 {
1255 public:
1256  TestAmpduReception ();
1257  virtual ~TestAmpduReception ();
1258 
1259 protected:
1260  virtual void DoSetup (void);
1261 
1262 private:
1263  virtual void DoRun (void);
1264 
1272  void RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1277  void RxFailure (Ptr<Packet> p);
1288  void IncrementSuccessBitmap (uint32_t size);
1293  void IncrementFailureBitmap (uint32_t size);
1294 
1298  void ResetBitmaps();
1299 
1305  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1306 
1311  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1316  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1321  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1326  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1331  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1336  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1337 
1342  void CheckPhyState (WifiPhyState expectedState);
1343 
1345 
1348 
1351 
1354 };
1355 
1357 : TestCase ("A-MPDU reception test"),
1358  m_rxSuccessBitmapAmpdu1 (0),
1359  m_rxSuccessBitmapAmpdu2 (0),
1360  m_rxFailureBitmapAmpdu1 (0),
1361  m_rxFailureBitmapAmpdu2 (0),
1362  m_rxDroppedBitmapAmpdu1 (0),
1363  m_rxDroppedBitmapAmpdu2 (0)
1364 {
1365 }
1366 
1368 {
1369  m_phy = 0;
1370 }
1371 
1372 void
1374 {
1381 }
1382 
1383 void
1384 TestAmpduReception::RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1385 {
1386  NS_LOG_FUNCTION (this << p << snr << txVector);
1387  if (IsAmpdu (p))
1388  {
1389  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (p);
1390  NS_ABORT_MSG_IF (mpdus.size () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1391  auto rxOkForMpdu = statusPerMpdu.begin ();
1392  for (const auto & mpdu : mpdus)
1393  {
1394  if (*rxOkForMpdu)
1395  {
1396  IncrementSuccessBitmap (mpdu->GetSize ());
1397  }
1398  else
1399  {
1400  IncrementFailureBitmap (mpdu->GetSize ());
1401  }
1402  ++rxOkForMpdu;
1403  }
1404  }
1405  else
1406  {
1408  }
1409 }
1410 
1411 void
1413 {
1414  if (size == 1030) //A-MPDU 1 - MPDU #1
1415  {
1417  }
1418  else if (size == 1130) //A-MPDU 1 - MPDU #2
1419  {
1420  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1421  }
1422  else if (size == 1230) //A-MPDU 1 - MPDU #3
1423  {
1424  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1425  }
1426  else if (size == 1330) //A-MPDU 2 - MPDU #1
1427  {
1429  }
1430  else if (size == 1430) //A-MPDU 2 - MPDU #2
1431  {
1432  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1433  }
1434  else if (size == 1530) //A-MPDU 2 - MPDU #3
1435  {
1436  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1437  }
1438 }
1439 
1440 void
1442 {
1443  NS_LOG_FUNCTION (this << p);
1444  if (IsAmpdu (p))
1445  {
1446  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (p);
1447  for (const auto & mpdu : mpdus)
1448  {
1449  IncrementFailureBitmap (mpdu->GetSize ());
1450  }
1451  }
1452  else
1453  {
1455  }
1456 }
1457 
1458 void
1460 {
1461  if (size == 1030) //A-MPDU 1 - MPDU #1
1462  {
1464  }
1465  else if (size == 1130) //A-MPDU 1 - MPDU #2
1466  {
1467  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1468  }
1469  else if (size == 1230) //A-MPDU 1 - MPDU #3
1470  {
1471  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1472  }
1473  else if (size == 1330) //A-MPDU 2 - MPDU #1
1474  {
1476  }
1477  else if (size == 1430) //A-MPDU 2 - MPDU #2
1478  {
1479  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1480  }
1481  else if (size == 1530) //A-MPDU 2 - MPDU #3
1482  {
1483  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1484  }
1485 }
1486 
1487 void
1489 {
1490  NS_LOG_FUNCTION (this << p << reason);
1491  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1492  {
1494  }
1495  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1496  {
1497  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1498  }
1499  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1500  {
1501  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1502  }
1503  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1504  {
1506  }
1507  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1508  {
1509  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1510  }
1511  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1512  {
1513  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1514  }
1515 }
1516 
1517 void
1519 {
1520  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1521 }
1522 
1523 void
1525 {
1526  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1527 }
1528 
1529 void
1531 {
1532  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1533 }
1534 
1535 void
1537 {
1538  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1539 }
1540 
1541 void
1543 {
1544  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1545 }
1546 
1547 void
1549 {
1550  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1551 }
1552 
1553 void
1555 {
1556  WifiPhyState currentState;
1557  PointerValue ptr;
1558  m_phy->GetAttribute ("State", ptr);
1559  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1560  currentState = state->GetState ();
1561  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1562 }
1563 
1564 void
1565 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1566 {
1567  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true, false);
1568 
1569  WifiMacHeader hdr;
1570  hdr.SetType (WIFI_MAC_QOSDATA);
1571  hdr.SetQosTid (0);
1572 
1573  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1574  for (size_t i = 0; i < 3; ++i)
1575  {
1576  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1577  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1578  }
1579  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1580 
1581  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
1582  psdu->SetDuration (txDuration);
1583  Ptr<Packet> pkt = psdu->GetPacket ()->Copy ();
1584 
1585  HeSigHeader heSig;
1586  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
1587  heSig.SetBssColor (txVector.GetBssColor ());
1588  heSig.SetChannelWidth (txVector.GetChannelWidth ());
1589  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
1590  pkt->AddHeader (heSig);
1591 
1592  LSigHeader sig;
1593  uint16_t length = ((ceil ((static_cast<double> (txDuration.GetNanoSeconds () - (20 * 1000)) / 1000) / 4.0) * 3) - 3 - 2);
1594  sig.SetLength (length);
1595  pkt->AddHeader (sig);
1596 
1597  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
1598  pkt->AddPacketTag (tag);
1599 
1600  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1601  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1602  txParams->psd = txPowerSpectrum;
1603  txParams->txPhy = 0;
1604  txParams->duration = txDuration;
1605  txParams->packet = pkt;
1606 
1607  m_phy->StartRx (txParams);
1608 }
1609 
1610 void
1612 {
1613  m_phy = CreateObject<SpectrumWifiPhy> ();
1615  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1616  m_phy->SetErrorRateModel (error);
1619 
1623 
1624  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1625  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1626  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1627 
1628  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1629  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1630  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1631  m_phy->SetFrameCaptureModel (frameCaptureModel);
1632 }
1633 
1634 void
1636 {
1637  RngSeedManager::SetSeed (1);
1638  RngSeedManager::SetRun (1);
1639  int64_t streamNumber = 1;
1640  double rxPowerDbm = -30;
1641  m_phy->AssignStreams (streamNumber);
1642 
1644  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1645  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1647 
1648  // A-MPDU 1
1649  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1650 
1651  // A-MPDU 2
1652  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1653 
1654  // All MPDUs of A-MPDU 1 should have been ignored.
1655  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1656  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1657  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1658 
1659  // All MPDUs of A-MPDU 2 should have been successfully received.
1660  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1661  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1662  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1663 
1664  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1665 
1667  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1668  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1670 
1671  // A-MPDU 1
1672  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1673 
1674  // A-MPDU 2
1675  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1676 
1677  // All MPDUs of A-MPDU 1 should have been received.
1678  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1679  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1680  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1681 
1682  // All MPDUs of A-MPDU 2 should have been ignored.
1683  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1684  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1685  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1686 
1687  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1688 
1690  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1691  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1693 
1694  // A-MPDU 1
1695  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1696 
1697  // A-MPDU 2
1698  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1699 
1700  // All MPDUs of A-MPDU 1 should have been ignored.
1701  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1702  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1703  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1704 
1705  // All MPDUs of A-MPDU 2 should have been successfully received.
1706  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1707  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1708  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1709 
1710  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1711 
1713  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1714  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1716 
1717  // A-MPDU 1
1718  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1719 
1720  // A-MPDU 2
1721  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1722 
1723  // All MPDUs of A-MPDU 1 should have been received.
1724  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1725  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1726  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1727 
1728  // All MPDUs of A-MPDU 2 should have been ignored.
1729  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1730  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1731  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1732 
1733  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1734 
1736  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1737  // 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).
1739 
1740  // A-MPDU 1
1741  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1742 
1743  // A-MPDU 2
1744  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1745 
1746  // All MPDUs of A-MPDU 1 should have been ignored.
1747  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1748  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1749  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1750 
1751  // All MPDUs of A-MPDU 2 should have been successfully received.
1752  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1753  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1754  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1755 
1756  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1757 
1759  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1760  // 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).
1762 
1763  // A-MPDU 1
1764  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1765 
1766  // A-MPDU 2
1767  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1768 
1769  // All MPDUs of A-MPDU 1 should have been received.
1770  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1771  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1772  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1773 
1774  // All MPDUs of A-MPDU 2 should have been ignored.
1775  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1776  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1777  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1778 
1779  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1780 
1782  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1783  // The second A-MPDU is received during the payload of MPDU #2.
1785 
1786  // A-MPDU 1
1787  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1788 
1789  // A-MPDU 2
1790  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1791 
1792  // All MPDUs of A-MPDU 1 should have been ignored.
1793  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1794  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1795  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1796 
1797  // All MPDUs of A-MPDU 2 should have been successfully received.
1798  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1799  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1800  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1801 
1802  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1803 
1805  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1806  // The second A-MPDU is received during the payload of MPDU #2.
1808 
1809  // A-MPDU 1
1810  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1811 
1812  // A-MPDU 2
1813  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1814 
1815  // All MPDUs of A-MPDU 1 should have been received.
1816  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1817  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1818  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1819 
1820  // All MPDUs of A-MPDU 2 should have been ignored.
1821  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1822  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1823  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1824 
1825  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1826 
1828  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1829  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1831 
1832  // A-MPDU 1
1833  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1834 
1835  // A-MPDU 2
1836  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1837 
1838  // All MPDUs of A-MPDU 1 should have been dropped.
1839  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1840  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1841  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1842 
1843  // All MPDUs of A-MPDU 2 should have been received with errors.
1844  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1845  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
1846  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1847 
1848  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
1849 
1851  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1852  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1854 
1855  // A-MPDU 1
1856  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1857 
1858  // A-MPDU 2
1859  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1860 
1861  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
1862  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1863  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1864  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1865 
1866  // All MPDUs of A-MPDU 2 should have been dropped as well.
1867  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1868  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1869  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1870 
1871  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
1872 
1874  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1875  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1877 
1878  // A-MPDU 1
1879  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1880 
1881  // A-MPDU 2
1882  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1883 
1884  // All MPDUs of A-MPDU 1 should have been received with errors.
1885  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1886  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1887  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1888 
1889  // All MPDUs of A-MPDU 2 should have been dropped.
1890  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1891  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1892  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1893 
1894  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
1895 
1897  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1898  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1900 
1901  // A-MPDU 1
1902  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1903 
1904  // A-MPDU 2
1905  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1906 
1907  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
1908  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1909  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1910  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1911 
1912  // 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)
1913  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1914  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1915  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1916 
1917  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
1918 
1920  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1921  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1923 
1924  // A-MPDU 1
1925  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1926 
1927  // A-MPDU 2
1928  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1929 
1930  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
1931  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1932  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1933  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1934 
1935  // All MPDUs of A-MPDU 2 should have been dropped as well.
1936  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1937  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1938  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1939 
1940  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
1941 
1943  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1944  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1946 
1947  // A-MPDU 1
1948  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1949 
1950  // A-MPDU 2
1951  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1952 
1953  // All MPDUs of A-MPDU 1 should have been received with errors.
1954  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1955  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1956  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1957 
1958  // All MPDUs of A-MPDU 2 should have been dropped.
1959  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1960  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1961  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1962 
1963  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
1964 
1966  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
1967  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1969 
1970  // A-MPDU 1
1971  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1972 
1973  // A-MPDU 2
1974  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
1975 
1976  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
1977  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1978  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1979  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1980 
1981  // All MPDUs of A-MPDU 2 should have been successfully received
1982  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1983  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1984  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1985 
1986  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
1987 
1989  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
1990  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1992 
1993  // A-MPDU 1
1994  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
1995 
1996  // A-MPDU 2
1997  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1998 
1999  // All MPDUs of A-MPDU 1 should have been successfully received.
2000  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2001  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2002  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2003 
2004  // All MPDUs of A-MPDU 2 should have been dropped.
2005  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2006  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2007  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2008 
2009  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2010 
2012  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2013  // 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).
2015 
2016  // A-MPDU 1
2017  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2018 
2019  // A-MPDU 2
2020  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2021 
2022  // All MPDUs of A-MPDU 1 should have been received with errors.
2023  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2024  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2025  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2026 
2027  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2028  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2029  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2030  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2031 
2032  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2033 
2035  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2036  // 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).
2038 
2039  // A-MPDU 1
2040  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2041 
2042  // A-MPDU 2
2043  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2044 
2045  // All MPDUs of A-MPDU 1 should have been successfully received.
2046  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2047  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2048  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2049 
2050  // All MPDUs of A-MPDU 2 should have been dropped.
2051  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2052  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2053  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2054 
2055  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2056 
2058  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2059  // 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).
2061 
2062  // A-MPDU 1
2063  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2064 
2065  // A-MPDU 2
2066  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2067 
2068  // All MPDUs of A-MPDU 1 should have been received with errors.
2069  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2070  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2071  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2072 
2073  // All MPDUs of A-MPDU 2 should have been dropped.
2074  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2075  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2076  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2077 
2078  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2079 
2081  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2082  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2084 
2085  // A-MPDU 1
2086  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2087 
2088  // A-MPDU 2
2089  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2090 
2091  // All MPDUs of A-MPDU 1 should have been received with errors.
2092  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2093  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2094  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2095 
2096  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2097  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2098  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2099  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2100 
2101  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2102 
2104  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2105  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2107 
2108  // A-MPDU 1
2109  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2110 
2111  // A-MPDU 2
2112  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2113 
2114  // All MPDUs of A-MPDU 1 should have been successfully received.
2115  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2116  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2117  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2118 
2119  // All MPDUs of A-MPDU 2 should have been dropped.
2120  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2121  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2122  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2123 
2124  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2125 
2127  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2128  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2130 
2131  // A-MPDU 1
2132  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2133 
2134  // A-MPDU 2
2135  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2136 
2137  // All MPDUs of A-MPDU 1 should have been received with errors.
2138  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2139  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2140  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2141 
2142  // All MPDUs of A-MPDU 2 should have been dropped.
2143  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2144  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2145  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2146 
2147  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2148 
2150  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2151  // The second A-MPDU is received during the payload of MPDU #2.
2153 
2154  // A-MPDU 1
2155  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2156 
2157  // A-MPDU 2
2158  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2159 
2160  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2161  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2162  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2163  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2164  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000110);
2165 
2166  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2167  // 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.
2168  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2169  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2170  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2171 
2172  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2173 
2174  Simulator::Run ();
2175  Simulator::Destroy ();
2176 }
2177 
2185 {
2186 public:
2188 };
2189 
2191  : TestSuite ("wifi-phy-reception", UNIT)
2192 {
2195  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2196  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2197  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2198 }
2199 
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.
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.
static const uint32_t packetSize
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.