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/mobility-helper.h"
23#include "ns3/multi-model-spectrum-channel.h"
24#include "ns3/config.h"
25#include "ns3/ap-wifi-mac.h"
26#include "ns3/packet-socket-address.h"
27#include "ns3/packet-socket-client.h"
28#include "ns3/packet-socket-helper.h"
29#include "ns3/packet-socket-server.h"
30#include "ns3/test.h"
31#include "ns3/double.h"
32#include "ns3/boolean.h"
33#include "ns3/pointer.h"
34#include "ns3/rng-seed-manager.h"
35#include "ns3/spectrum-wifi-helper.h"
36#include "ns3/wifi-net-device.h"
37#include "ns3/wifi-spectrum-value-helper.h"
38#include "ns3/spectrum-wifi-phy.h"
39#include "ns3/nist-error-rate-model.h"
40#include "ns3/wifi-mac-header.h"
41#include "ns3/ampdu-tag.h"
42#include "ns3/wifi-spectrum-signal-parameters.h"
43#include "ns3/wifi-utils.h"
44#include "ns3/threshold-preamble-detection-model.h"
45#include "ns3/simple-frame-capture-model.h"
46#include "ns3/wifi-mac-queue-item.h"
47#include "ns3/mpdu-aggregator.h"
48#include "ns3/wifi-psdu.h"
49#include "ns3/he-ppdu.h"
50#include "ns3/he-phy.h"
51
52using namespace ns3;
53
54NS_LOG_COMPONENT_DEFINE ("WifiPhyReceptionTest");
55
56static const uint8_t CHANNEL_NUMBER = 36;
57static const uint32_t FREQUENCY = 5180; // MHz
58static const uint16_t CHANNEL_WIDTH = 20; // MHz
59static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
60
68{
69public:
72
73protected:
74 void DoSetup (void) override;
75 void DoTeardown (void) override;
81 void SendPacket (double rxPowerDbm);
89 void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
90 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
95 void RxFailure (Ptr<WifiPsdu> psdu);
98
99private:
100 void DoRun (void) override;
101
106 void CheckPhyState (WifiPhyState expectedState);
111 void DoCheckPhyState (WifiPhyState expectedState);
117 void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
118
119 uint64_t m_uid;
120};
121
123 : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
124 m_countRxSuccess (0),
125 m_countRxFailure (0),
126 m_uid (0)
127{
128}
129
130void
132{
133 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
134
135 Ptr<Packet> pkt = Create<Packet> (1000);
136 WifiMacHeader hdr;
137
139 hdr.SetQosTid (0);
140
141 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
142 Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
143
144 Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
145
146 Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
147
148 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
149 txParams->psd = txPowerSpectrum;
150 txParams->txPhy = 0;
151 txParams->duration = txDuration;
152 txParams->ppdu = ppdu;
153
154 m_phy->StartRx (txParams);
155}
156
157void
159{
160 //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
161 Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
162}
163
164void
166{
167 WifiPhyState currentState;
168 PointerValue ptr;
169 m_phy->GetAttribute ("State", ptr);
170 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
171 currentState = state->GetState ();
172 NS_LOG_FUNCTION (this << currentState);
173 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
174}
175
176void
178{
179 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
180 NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
181}
182
183void
185 WifiTxVector txVector, std::vector<bool> statusPerMpdu)
186{
187 NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
189}
190
191void
193{
194 NS_LOG_FUNCTION (this << *psdu);
196}
197
199{
200 m_phy = 0;
201}
202
203void
205{
206 m_phy = CreateObject<SpectrumWifiPhy> ();
208 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
209 m_phy->SetErrorRateModel (error);
213
214 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
215 preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
216 preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
217 m_phy->SetPreambleDetectionModel (preambleDetectionModel);
218}
219
220void
222{
223 m_phy->Dispose ();
224 m_phy = 0;
225}
226
227void
229{
230 RngSeedManager::SetSeed (1);
231 RngSeedManager::SetRun (1);
232 int64_t streamNumber = 0;
233 m_phy->AssignStreams (streamNumber);
234
235 //RX power > CCA-ED > CCA-PD
236 double rxPowerDbm = -50;
237
238 // CASE 1: send one packet and check PHY state:
239 // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
240 // otherwise it should be IDLE.
241
242 Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
243 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
246 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
249 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
252 // Packet should have been successfully received
254
255 // CASE 2: send two packets with same power within the 4us window and check PHY state:
256 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
257 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
258 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
259
260 Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
261 Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
262 // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
265 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
268 // 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
270
271 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
272 // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
273 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
274 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
275
276 Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
277 Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
278 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
281 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
284 // 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
286
287 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
288 // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
289 // but payload reception should fail (SNR too low to decode the modulation).
290
291 Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
292 Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
293 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
296 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
299 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
300 // 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.
305 // In this case, the first packet should be marked as a failure
307
308 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
309 // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
310 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
311 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
312
313 Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
314 Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
315 // At 6us (hence 4us after the last signal is received), no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
318 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
321 // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
323
324 // CCA-PD < RX power < CCA-ED
325 rxPowerDbm = -70;
326
327 // CASE 6: send one packet and check PHY state:
328 // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
329 // otherwise it should be IDLE.
330
331 Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
332 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
335 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
338 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
341 // Packet should have been successfully received
343
344 // CASE 7: send two packets with same power within the 4us window and check PHY state:
345 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
346 // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
347
348 Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
349 Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
350 // At 4us, STA PHY STATE should stay IDLE
352 // 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
354
355 // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
356 // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
357 // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
358
359 Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
360 Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
361 // At 4us, STA PHY STATE should stay IDLE
363 // 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
365
366 // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
367 // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
368 // but payload reception should fail (SNR too low to decode the modulation).
369
370 Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
371 Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
372 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
375 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
378 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
381 // In this case, the first packet should be marked as a failure
383
384 // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
385 // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
386 // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
387
388 Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
389 Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
390 // At 4us, STA PHY STATE should stay IDLE
392 // 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
394
395 // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
396 // preamble detection should succeed and PHY state should move to RX.
397
398 rxPowerDbm = -81;
399
400 Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
401 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
404 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
407 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
410
411 // RX power < CCA-PD < CCA-ED
412 rxPowerDbm = -83;
413
414 //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
415 //preamble detection should fail and PHY should be kept in IDLE state.
416
417 Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
418 // At 4us, STA PHY state should be IDLE
420
421 Simulator::Run ();
422 Simulator::Destroy ();
423}
424
432{
433public:
436
437protected:
438 void DoSetup (void) override;
439 void DoTeardown (void) override;
445 void SendPacket (double rxPowerDbm);
453 void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
454 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
459 void RxFailure (Ptr<WifiPsdu> psdu);
462
463private:
464 void DoRun (void) override;
465
470 void CheckPhyState (WifiPhyState expectedState);
475 void DoCheckPhyState (WifiPhyState expectedState);
481 void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
482
483 uint64_t m_uid;
484};
485
487: TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
488 m_countRxSuccess (0),
489 m_countRxFailure (0),
490 m_uid (0)
491{
492}
493
494void
496{
497 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
498
499 Ptr<Packet> pkt = Create<Packet> (1000);
500 WifiMacHeader hdr;
501
503 hdr.SetQosTid (0);
504
505 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
506 Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
507
508 Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
509
510 Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
511
512 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
513 txParams->psd = txPowerSpectrum;
514 txParams->txPhy = 0;
515 txParams->duration = txDuration;
516 txParams->ppdu = ppdu;
517
518 m_phy->StartRx (txParams);
519}
520
521void
523{
524 //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
525 Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
526}
527
528void
530{
531 WifiPhyState currentState;
532 PointerValue ptr;
533 m_phy->GetAttribute ("State", ptr);
534 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
535 currentState = state->GetState ();
536 NS_LOG_FUNCTION (this << currentState);
537 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
538}
539
540void
542{
543 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
544 NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
545}
546
547void
549 WifiTxVector txVector, std::vector<bool> statusPerMpdu)
550{
551 NS_LOG_FUNCTION (this << *psdu << txVector);
553}
554
555void
557{
558 NS_LOG_FUNCTION (this << *psdu);
560}
561
563{
564 m_phy = 0;
565}
566
567void
569{
570 m_phy = CreateObject<SpectrumWifiPhy> ();
572 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
573 m_phy->SetErrorRateModel (error);
577
578 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
579 preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
580 preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
581 m_phy->SetPreambleDetectionModel (preambleDetectionModel);
582
583 Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
584 frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
585 frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
586 m_phy->SetFrameCaptureModel (frameCaptureModel);
587}
588
589void
591{
592 m_phy->Dispose ();
593 m_phy = 0;
594}
595
596void
598{
599 RngSeedManager::SetSeed (1);
600 RngSeedManager::SetRun (1);
601 int64_t streamNumber = 1;
602 m_phy->AssignStreams (streamNumber);
603
604 //RX power > CCA-ED > CCA-PD
605 double rxPowerDbm = -50;
606
607 // CASE 1: send one packet and check PHY state:
608 // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
609 // otherwise it should be IDLE.
610
611 Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
612 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
615 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
618 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
621 // Packet should have been successfully received
622 Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
623
624 // CASE 2: send two packets with same power within the 4us window and check PHY state:
625 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
626 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
627 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
628
629 Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
630 Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
631 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
634 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
637 // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
638 Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
639
640 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
641 // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
642 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
643 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
644
645 Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
646 Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
647 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
650 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
653 // 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
654 Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
655
656 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
657 // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
658 // but payload reception should fail (SNR too low to decode the modulation).
659
660 Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
661 Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
662 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
665 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
668 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
669 // 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.
674 // In this case, the first packet should be marked as a failure
675 Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
676
677 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
678 // PHY preamble detection should switch because a higher packet is received within the 4us window,
679 // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
680 // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
681
682 Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
683 Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
684 // At 4us, STA PHY STATE should stay IDLE
686 // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
689 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
692 // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
693 Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
694
695 // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
696 // PHY preamble detection should switch because a higher packet is received within the 4us window,
697 // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
698 // Payload reception should fail (SNR too low to decode the modulation).
699
700 Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
701 Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
702 // At 4us, STA PHY STATE should stay IDLE
704 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
707 // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
710 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
713 // In this case, the second packet should be marked as a failure
714 Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
715
716 // CASE 7: send two packets with same power at the exact same time and check PHY state:
717 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
718 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
719 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
720
721 Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
722 Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
723 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
726 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
729 // 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
730 Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
731
732 // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
733 // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
734 // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
735 // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
736
737 Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
738 Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
739 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
742 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
745 // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
746 Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
747
748 // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
749 // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
750 // but payload reception should fail (SNR too low to decode the modulation).
751
752 Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
753 Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
754 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
757 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
760 // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
763 // In this case, the first packet should be marked as a failure
764 Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
765
766 // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
767 // PHY preamble detection should switch because a higher packet is received within the 4us window,
768 // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
769 // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
770
771 Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
772 Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
773 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
776 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
779 // 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
780 Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
781
782 // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
783 // PHY preamble detection should switch because a higher packet is received within the 4us window,
784 // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
785 // Payload reception should fail (SNR too low to decode the modulation).
786
787 Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
788 Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
789 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
792 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
795 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
798 // In this case, the second packet should be marked as a failure
799 Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
800
801 // CCA-PD < RX power < CCA-ED
802 rxPowerDbm = -70;
803
804 // CASE 12: send one packet and check PHY state:
805 // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
806 // otherwise it should be IDLE.
807
808 Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
809 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
812 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
815 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
818 // Packet should have been successfully received
819 Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
820
821 // CASE 13: send two packets with same power within the 4us window and check PHY state:
822 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
823 // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
824
825 Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
826 Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
827 // At 4us, STA PHY STATE should stay IDLE
829 // 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
830 Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
831
832 // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
833 // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
834 // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
835
836 Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
837 Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
838 // At 4us, STA PHY STATE should stay IDLE
840 // 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
841 Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
842
843 // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
844 // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
845 // but payload reception should fail (SNR too low to decode the modulation).
846
847 Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
848 Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
849 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
852 // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
855 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
858 // In this case, the first packet should be marked as a failure
859 Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
860
861 // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
862 // PHY preamble detection should switch because a higher packet is received within the 4us window,
863 // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
864 // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
865
866 Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
867 Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
868 // At 4us, STA PHY STATE should stay IDLE
870 // At 6us, STA PHY STATE should stay IDLE
872 // 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
873 Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
874
875 // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
876 // PHY preamble detection should switch because a higher packet is received within the 4us window,
877 // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
878 // Payload reception should fail (SNR too low to decode the modulation).
879
880 Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
881 Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
882 // At 4us, STA PHY STATE should stay IDLE
884 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
887 // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
890 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
893 // In this case, the second packet should be marked as a failure
894 Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
895
896 rxPowerDbm = -50;
897 // CASE 18: send two packets with second one 50 dB higher within the 4us window
898
899 Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
900 Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
901 // The second packet should be received successfully
902 Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
903
904 // CASE 19: send two packets with second one 10 dB higher within the 4us window
905
906 Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
907 Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
908 // The second packet should be captured, but not decoded since SNR to low for used MCS
909 Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
910
911 // CASE 20: send two packets with second one 50 dB higher in the same time
912
913 Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
914 Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
915 // The second packet should be received successfully, same as in CASE 13
916 Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
917
918 // CASE 21: send two packets with second one 10 dB higher in the same time
919
920 Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
921 Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
922 // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
923 Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
924
925 Simulator::Run ();
926 Simulator::Destroy ();
927}
928
936{
937public:
940
941protected:
942 void DoSetup (void) override;
943 void DoTeardown (void) override;
944
945private:
946 void DoRun (void) override;
947
951 void Reset (void);
957 void SendPacket (double rxPowerDbm, uint32_t packetSize);
965 void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
966 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
973
990
992
997
998 uint64_t m_uid;
999};
1000
1002: TestCase ("Simple frame capture model test"),
1003 m_rxSuccess1000B (false),
1004 m_rxSuccess1500B (false),
1005 m_rxDropped1000B (false),
1006 m_rxDropped1500B (false),
1007 m_uid (0)
1008{
1009}
1010
1011void
1013{
1014 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1015
1016 Ptr<Packet> pkt = Create<Packet> (packetSize);
1017 WifiMacHeader hdr;
1018
1020 hdr.SetQosTid (0);
1021
1022 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1023 Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1024
1025 Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1026
1027 Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1028
1029 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1030 txParams->psd = txPowerSpectrum;
1031 txParams->txPhy = 0;
1032 txParams->duration = txDuration;
1033 txParams->ppdu = ppdu;
1034
1035 m_phy->StartRx (txParams);
1036}
1037
1038void
1040 WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1041{
1042 NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
1043 NS_ASSERT (!psdu->IsAggregate () || psdu->IsSingle ());
1044 if (psdu->GetSize () == 1030)
1045 {
1046 m_rxSuccess1000B = true;
1047 }
1048 else if (psdu->GetSize () == 1530)
1049 {
1050 m_rxSuccess1500B = true;
1051 }
1052}
1053
1054void
1056{
1057 NS_LOG_FUNCTION (this << p << reason);
1058 if (p->GetSize () == 1030)
1059 {
1060 m_rxDropped1000B = true;
1061 }
1062 else if (p->GetSize () == 1530)
1063 {
1064 m_rxDropped1500B = true;
1065 }
1066}
1067
1068void
1070{
1071 m_rxSuccess1000B = false;
1072 m_rxSuccess1500B = false;
1073 m_rxDropped1000B = false;
1074 m_rxDropped1500B = false;
1075}
1076
1077void
1079{
1080 NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1081}
1082
1083void
1085{
1086 NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1087}
1088void
1090{
1091 NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1092}
1093
1094void
1096{
1097 NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1098}
1099
1101{
1102 m_phy = 0;
1103}
1104
1105void
1107{
1108 m_phy = CreateObject<SpectrumWifiPhy> ();
1110 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1111 m_phy->SetErrorRateModel (error);
1113
1116
1117 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1118 preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1119 m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1120
1121 Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1122 frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1123 frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1124 m_phy->SetFrameCaptureModel (frameCaptureModel);
1125}
1126
1127void
1129{
1130 m_phy->Dispose ();
1131 m_phy = 0;
1132}
1133
1134void
1136{
1137 RngSeedManager::SetSeed (1);
1138 RngSeedManager::SetRun (1);
1139 int64_t streamNumber = 2;
1140 double rxPowerDbm = -30;
1141 m_phy->AssignStreams (streamNumber);
1142
1143 // CASE 1: send two packets with same power within the capture window:
1144 // PHY should not switch reception because they have same power.
1145
1146 Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1147 Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1148 Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1149 Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1150
1151 // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1152 // PHY should not switch reception because first one has higher power.
1153
1154 Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1155 Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1156 Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1157 Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1158 Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1159
1160 // CASE 3: send two packets with second one 6 dB higher within the capture window:
1161 // PHY should switch reception because the second one has a higher power.
1162
1163 Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1164 Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1165 Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1166 Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1167 Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1168
1169 // CASE 4: send two packets with second one 6 dB higher after the capture window:
1170 // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1171
1172 Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1173 Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1174 Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1175 Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1176
1177 Simulator::Run ();
1178 Simulator::Destroy ();
1179}
1180
1188{
1189public:
1191 virtual ~TestPhyHeadersReception ();
1192
1193protected:
1194 void DoSetup (void) override;
1195 void DoTeardown (void) override;
1201 void SendPacket (double rxPowerDbm);
1202
1203private:
1204 void DoRun (void) override;
1205
1210 void CheckPhyState (WifiPhyState expectedState);
1215 void DoCheckPhyState (WifiPhyState expectedState);
1216
1217 uint64_t m_uid;
1218};
1219
1221: TestCase ("PHY headers reception test"),
1222 m_uid (0)
1223{
1224}
1225
1226void
1228{
1229 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1230
1231 Ptr<Packet> pkt = Create<Packet> (1000);
1232 WifiMacHeader hdr;
1233
1235 hdr.SetQosTid (0);
1236
1237 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1238 Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1239
1240 Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1241
1242 Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1243
1244 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1245 txParams->psd = txPowerSpectrum;
1246 txParams->txPhy = 0;
1247 txParams->duration = txDuration;
1248 txParams->ppdu = ppdu;
1249
1250 m_phy->StartRx (txParams);
1251}
1252
1253void
1255{
1256 //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
1257 Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1258}
1259
1260void
1262{
1263 WifiPhyState currentState;
1264 PointerValue ptr;
1265 m_phy->GetAttribute ("State", ptr);
1266 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1267 currentState = state->GetState ();
1268 NS_LOG_FUNCTION (this << currentState);
1269 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1270}
1271
1272
1274{
1275 m_phy = 0;
1276}
1277
1278void
1280{
1281 m_phy = CreateObject<SpectrumWifiPhy> ();
1283 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1284 m_phy->SetErrorRateModel (error);
1286}
1287
1288void
1290{
1291 m_phy->Dispose ();
1292 m_phy = 0;
1293}
1294
1295void
1297{
1298 RngSeedManager::SetSeed (1);
1299 RngSeedManager::SetRun (1);
1300 int64_t streamNumber = 0;
1301 m_phy->AssignStreams (streamNumber);
1302
1303 // RX power > CCA-ED
1304 double rxPowerDbm = -50;
1305
1306 // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1307 // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1308
1309 Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1310 Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1311 // At 10 us, STA PHY STATE should be CCA_BUSY.
1312 Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1313 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to CCA_BUSY.
1314 Simulator::Schedule (Seconds (1.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1315 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1316 Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1317 Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1318
1319 // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1320 // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1321
1322 Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1323 Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1324 // At 10 us, STA PHY STATE should be CCA_BUSY.
1325 Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1326 // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception should have succeeded.
1327 Simulator::Schedule (Seconds (2.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1328 Simulator::Schedule (Seconds (2.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1329 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1330 // 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.
1331 Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1332 Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1333 Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1334 Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1335
1336 // 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:
1337 // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1338
1339 Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1340 Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1341 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be kept to CCA_BUSY.
1342 Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1343 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1344 // 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.
1345 Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1346 Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1347 Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1348 Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1349
1350 // 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:
1351 // PHY header reception should succeed.
1352
1353 Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1354 Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1355 // At 10 us, STA PHY STATE should be CCA_BUSY.
1356 Simulator::Schedule (Seconds (4.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1357 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1358 Simulator::Schedule (Seconds (4.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1359 Simulator::Schedule (Seconds (4.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1360 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1361 // 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.
1362 Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1363 Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1364 Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1365 Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1366
1367 // RX power < CCA-ED
1368 rxPowerDbm = -70;
1369
1370 // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1371 // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1372
1373 Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1374 Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1375 // At 10 us, STA PHY STATE should be CCA_BUSY.
1376 Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1377 // 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.
1378 Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1379 Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1380
1381 // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1382 // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1383
1384 Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1385 Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1386 // At 10 us, STA PHY STATE should be CCA_BUSY.
1387 Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1388 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1389 Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1390 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1391 Simulator::Schedule (Seconds (6.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1392 Simulator::Schedule (Seconds (6.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1393 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1394 Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1395 Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1396
1397 // 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:
1398 // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1399
1400 Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1401 Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1402 // At 10 us, STA PHY STATE should be CCA_BUSY.
1403 Simulator::Schedule (Seconds (7.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1404 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1405 Simulator::Schedule (Seconds (7.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1406 // At 44 us (end of HE-SIG), STA PHY STATE should be not have moved to RX since reception of HE-SIG should have failed.
1407 Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1408 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1409 Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1410 Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1411
1412 // 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:
1413 // PHY header reception should succeed.
1414
1415 Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1416 Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1417 // At 10 us, STA PHY STATE should be CCA_BUSY.
1418 Simulator::Schedule (Seconds (8.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1419 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1420 Simulator::Schedule (Seconds (8.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1421 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1422 Simulator::Schedule (Seconds (8.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1423 Simulator::Schedule (Seconds (8.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1424 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1425 Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1426 Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1427
1428 Simulator::Run ();
1429 Simulator::Destroy ();
1430}
1431
1439{
1440public:
1442 virtual ~TestAmpduReception ();
1443
1444protected:
1445 void DoSetup (void) override;
1446 void DoTeardown (void) override;
1447
1448private:
1449 void DoRun (void) override;
1450
1458 void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
1459 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1464 void RxFailure (Ptr<WifiPsdu> psdu);
1475 void IncrementSuccessBitmap (uint32_t size);
1480 void IncrementFailureBitmap (uint32_t size);
1481
1485 void ResetBitmaps();
1486
1492 void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1493
1498 void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1503 void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1508 void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1513 void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1518 void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1523 void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1524
1529 void CheckPhyState (WifiPhyState expectedState);
1530
1532
1535
1538
1541
1542 uint64_t m_uid;
1543};
1544
1546: TestCase ("A-MPDU reception test"),
1547 m_rxSuccessBitmapAmpdu1 (0),
1548 m_rxSuccessBitmapAmpdu2 (0),
1549 m_rxFailureBitmapAmpdu1 (0),
1550 m_rxFailureBitmapAmpdu2 (0),
1551 m_rxDroppedBitmapAmpdu1 (0),
1552 m_rxDroppedBitmapAmpdu2 (0),
1553 m_uid (0)
1554{
1555}
1556
1558{
1559 m_phy = 0;
1560}
1561
1562void
1564{
1571}
1572
1573void
1575 WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1576{
1577 NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
1578 if (statusPerMpdu.empty ()) //wait for the whole A-MPDU
1579 {
1580 return;
1581 }
1582 NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1583 auto rxOkForMpdu = statusPerMpdu.begin ();
1584 for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1585 {
1586 if (*rxOkForMpdu)
1587 {
1588 IncrementSuccessBitmap ((*mpdu)->GetSize ());
1589 }
1590 else
1591 {
1592 IncrementFailureBitmap ((*mpdu)->GetSize ());
1593 }
1594 ++rxOkForMpdu;
1595 }
1596}
1597
1598void
1600{
1601 if (size == 1030) //A-MPDU 1 - MPDU #1
1602 {
1604 }
1605 else if (size == 1130) //A-MPDU 1 - MPDU #2
1606 {
1607 m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1608 }
1609 else if (size == 1230) //A-MPDU 1 - MPDU #3
1610 {
1611 m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1612 }
1613 else if (size == 1330) //A-MPDU 2 - MPDU #1
1614 {
1616 }
1617 else if (size == 1430) //A-MPDU 2 - MPDU #2
1618 {
1619 m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1620 }
1621 else if (size == 1530) //A-MPDU 2 - MPDU #3
1622 {
1623 m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1624 }
1625}
1626
1627void
1629{
1630 NS_LOG_FUNCTION (this << *psdu);
1631 for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1632 {
1633 IncrementFailureBitmap ((*mpdu)->GetSize ());
1634 }
1635}
1636
1637void
1639{
1640 if (size == 1030) //A-MPDU 1 - MPDU #1
1641 {
1643 }
1644 else if (size == 1130) //A-MPDU 1 - MPDU #2
1645 {
1646 m_rxFailureBitmapAmpdu1 |= (1 << 1);
1647 }
1648 else if (size == 1230) //A-MPDU 1 - MPDU #3
1649 {
1650 m_rxFailureBitmapAmpdu1 |= (1 << 2);
1651 }
1652 else if (size == 1330) //A-MPDU 2 - MPDU #1
1653 {
1655 }
1656 else if (size == 1430) //A-MPDU 2 - MPDU #2
1657 {
1658 m_rxFailureBitmapAmpdu2 |= (1 << 1);
1659 }
1660 else if (size == 1530) //A-MPDU 2 - MPDU #3
1661 {
1662 m_rxFailureBitmapAmpdu2 |= (1 << 2);
1663 }
1664}
1665
1666void
1668{
1669 NS_LOG_FUNCTION (this << p << reason);
1670 if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1671 {
1673 }
1674 else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1675 {
1676 m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1677 }
1678 else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1679 {
1680 m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1681 }
1682 else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1683 {
1685 }
1686 else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1687 {
1688 m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1689 }
1690 else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1691 {
1692 m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1693 }
1694}
1695
1696void
1698{
1699 NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1700}
1701
1702void
1704{
1705 NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1706}
1707
1708void
1710{
1711 NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1712}
1713
1714void
1716{
1717 NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1718}
1719
1720void
1722{
1723 NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1724}
1725
1726void
1728{
1729 NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1730}
1731
1732void
1734{
1735 WifiPhyState currentState;
1736 PointerValue ptr;
1737 m_phy->GetAttribute ("State", ptr);
1738 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1739 currentState = state->GetState ();
1740 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1741}
1742
1743void
1744TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1745{
1746 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true);
1747
1748 WifiMacHeader hdr;
1750 hdr.SetQosTid (0);
1751
1752 std::vector<Ptr<WifiMacQueueItem>> mpduList;
1753 for (size_t i = 0; i < 3; ++i)
1754 {
1755 Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1756 mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1757 }
1758 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1759
1760 Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1761
1762 Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1763
1764 Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1765
1766 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1767 txParams->psd = txPowerSpectrum;
1768 txParams->txPhy = 0;
1769 txParams->duration = txDuration;
1770 txParams->ppdu = ppdu;
1771
1772 m_phy->StartRx (txParams);
1773}
1774
1775void
1777{
1778 m_phy = CreateObject<SpectrumWifiPhy> ();
1780 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1781 m_phy->SetErrorRateModel (error);
1783
1787
1788 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1789 preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1790 m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1791
1792 Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1793 frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1794 frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1795 m_phy->SetFrameCaptureModel (frameCaptureModel);
1796}
1797
1798void
1800{
1801 m_phy->Dispose ();
1802 m_phy = 0;
1803}
1804
1805void
1807{
1808 RngSeedManager::SetSeed (1);
1809 RngSeedManager::SetRun (2);
1810 int64_t streamNumber = 1;
1811 double rxPowerDbm = -30;
1812 m_phy->AssignStreams (streamNumber);
1813
1815 // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1816 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1818
1819 // A-MPDU 1
1820 Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1821
1822 // A-MPDU 2
1823 Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1824
1825 // All MPDUs of A-MPDU 1 should have been ignored.
1826 Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1827 Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1828 Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1829
1830 // All MPDUs of A-MPDU 2 should have been successfully received.
1831 Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1832 Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1833 Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1834
1835 Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1836
1838 // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1839 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1841
1842 // A-MPDU 1
1843 Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1844
1845 // A-MPDU 2
1846 Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1847
1848 // All MPDUs of A-MPDU 1 should have been received.
1849 Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1850 Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1851 Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1852
1853 // All MPDUs of A-MPDU 2 should have been ignored.
1854 Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1855 Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1856 Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1857
1858 Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1859
1861 // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1862 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1864
1865 // A-MPDU 1
1866 Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1867
1868 // A-MPDU 2
1869 Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1870
1871 // All MPDUs of A-MPDU 1 should have been ignored.
1872 Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1873 Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1874 Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1875
1876 // All MPDUs of A-MPDU 2 should have been successfully received.
1877 Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1878 Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1879 Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1880
1881 Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1882
1884 // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1885 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1887
1888 // A-MPDU 1
1889 Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1890
1891 // A-MPDU 2
1892 Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1893
1894 // All MPDUs of A-MPDU 1 should have been received.
1895 Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1896 Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1897 Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1898
1899 // All MPDUs of A-MPDU 2 should have been ignored.
1900 Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1901 Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1902 Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1903
1904 Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1905
1907 // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1908 // 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).
1910
1911 // A-MPDU 1
1912 Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1913
1914 // A-MPDU 2
1915 Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1916
1917 // All MPDUs of A-MPDU 1 should have been ignored.
1918 Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1919 Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1920 Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1921
1922 // All MPDUs of A-MPDU 2 should have been successfully received.
1923 Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1924 Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1925 Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1926
1927 Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1928
1930 // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1931 // 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).
1933
1934 // A-MPDU 1
1935 Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1936
1937 // A-MPDU 2
1938 Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1939
1940 // All MPDUs of A-MPDU 1 should have been received.
1941 Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1942 Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1943 Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1944
1945 // All MPDUs of A-MPDU 2 should have been ignored.
1946 Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1947 Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1948 Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1949
1950 Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1951
1953 // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1954 // The second A-MPDU is received during the payload of MPDU #2.
1956
1957 // A-MPDU 1
1958 Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1959
1960 // A-MPDU 2
1961 Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1962
1963 // All MPDUs of A-MPDU 1 should have been ignored.
1964 Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1965 Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1966 Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1967
1968 // All MPDUs of A-MPDU 2 should have been successfully received.
1969 Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1970 Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1971 Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1972
1973 Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1974
1976 // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1977 // The second A-MPDU is received during the payload of MPDU #2.
1979
1980 // A-MPDU 1
1981 Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1982
1983 // A-MPDU 2
1984 Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1985
1986 // All MPDUs of A-MPDU 1 should have been received.
1987 Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1988 Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1989 Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1990
1991 // All MPDUs of A-MPDU 2 should have been ignored.
1992 Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1993 Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1994 Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1995
1996 Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1997
1999 // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2000 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2002
2003 // A-MPDU 1
2004 Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2005
2006 // A-MPDU 2
2007 Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2008
2009 // All MPDUs of A-MPDU 1 should have been dropped.
2010 Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2011 Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2012 Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2013
2014 // All MPDUs of A-MPDU 2 should have been received with errors.
2015 Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2016 Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
2017 Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2018
2019 Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
2020
2022 // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2023 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2025
2026 // A-MPDU 1
2027 Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2028
2029 // A-MPDU 2
2030 Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2031
2032 // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
2033 Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2034 Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2035 Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2036
2037 // All MPDUs of A-MPDU 2 should have been dropped as well.
2038 Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2039 Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2040 Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2041
2042 Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
2043
2045 // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2046 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2048
2049 // A-MPDU 1
2050 Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2051
2052 // A-MPDU 2
2053 Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2054
2055 // All MPDUs of A-MPDU 1 should have been received with errors.
2056 Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2057 Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2058 Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2059
2060 // All MPDUs of A-MPDU 2 should have been dropped.
2061 Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2062 Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2063 Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2064
2065 Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
2066
2068 // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2069 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2071
2072 // A-MPDU 1
2073 Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2074
2075 // A-MPDU 2
2076 Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2077
2078 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2079 Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2080 Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2081 Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2082
2083 // 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)
2084 Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2085 Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2086 Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2087
2088 Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2089
2091 // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2092 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2094
2095 // A-MPDU 1
2096 Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2097
2098 // A-MPDU 2
2099 Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2100
2101 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2102 Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2103 Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2104 Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2105
2106 // All MPDUs of A-MPDU 2 should have been dropped as well.
2107 Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2108 Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2109 Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2110
2111 Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2112
2114 // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2115 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2117
2118 // A-MPDU 1
2119 Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2120
2121 // A-MPDU 2
2122 Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2123
2124 // All MPDUs of A-MPDU 1 should have been received with errors.
2125 Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2126 Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2127 Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2128
2129 // All MPDUs of A-MPDU 2 should have been dropped.
2130 Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2131 Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2132 Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2133
2134 Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2135
2137 // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2138 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2140
2141 // A-MPDU 1
2142 Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2143
2144 // A-MPDU 2
2145 Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2146
2147 // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2148 Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2149 Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2150 Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2151
2152 // All MPDUs of A-MPDU 2 should have been successfully received
2153 Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2154 Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2155 Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2156
2157 Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2158
2160 // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2161 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2163
2164 // A-MPDU 1
2165 Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2166
2167 // A-MPDU 2
2168 Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2169
2170 // All MPDUs of A-MPDU 1 should have been successfully received.
2171 Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2172 Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2173 Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2174
2175 // All MPDUs of A-MPDU 2 should have been dropped.
2176 Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2177 Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2178 Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2179
2180 Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2181
2183 // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2184 // 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).
2186
2187 // A-MPDU 1
2188 Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2189
2190 // A-MPDU 2
2191 Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2192
2193 // All MPDUs of A-MPDU 1 should have been received with errors.
2194 Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2195 Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2196 Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2197
2198 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2199 Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2200 Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2201 Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2202
2203 Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2204
2206 // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2207 // 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).
2209
2210 // A-MPDU 1
2211 Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2212
2213 // A-MPDU 2
2214 Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2215
2216 // All MPDUs of A-MPDU 1 should have been successfully received.
2217 Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2218 Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2219 Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2220
2221 // All MPDUs of A-MPDU 2 should have been dropped.
2222 Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2223 Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2224 Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2225
2226 Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2227
2229 // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2230 // 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).
2232
2233 // A-MPDU 1
2234 Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2235
2236 // A-MPDU 2
2237 Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2238
2239 // All MPDUs of A-MPDU 1 should have been received with errors.
2240 Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2241 Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2242 Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2243
2244 // All MPDUs of A-MPDU 2 should have been dropped.
2245 Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2246 Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2247 Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2248
2249 Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2250
2252 // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2253 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2255
2256 // A-MPDU 1
2257 Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2258
2259 // A-MPDU 2
2260 Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2261
2262 // All MPDUs of A-MPDU 1 should have been received with errors.
2263 Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2264 Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2265 Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2266
2267 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2268 Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2269 Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2270 Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2271
2272 Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2273
2275 // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2276 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2278
2279 // A-MPDU 1
2280 Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2281
2282 // A-MPDU 2
2283 Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2284
2285 // All MPDUs of A-MPDU 1 should have been successfully received.
2286 Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2287 Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2288 Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2289
2290 // All MPDUs of A-MPDU 2 should have been dropped.
2291 Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2292 Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2293 Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2294
2295 Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2296
2298 // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2299 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2301
2302 // A-MPDU 1
2303 Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2304
2305 // A-MPDU 2
2306 Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2307
2308 // All MPDUs of A-MPDU 1 should have been received with errors.
2309 Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2310 Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2311 Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2312
2313 // All MPDUs of A-MPDU 2 should have been dropped.
2314 Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2315 Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2316 Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2317
2318 Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2319
2321 // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2322 // The second A-MPDU is received during the payload of MPDU #2.
2324
2325 // A-MPDU 1
2326 Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2327
2328 // A-MPDU 2
2329 Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2330
2331 // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2332 // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2333 Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2334 Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2335 Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2336
2337 // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2338 // 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.
2339 Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2340 Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2341 Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2342
2343 Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2344
2345 Simulator::Run ();
2346 Simulator::Destroy ();
2347}
2348
2370{
2371public:
2377
2384 void Dropped (std::string context, Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
2388 void CheckResults (void);
2389
2390private:
2391 void DoRun (void) override;
2392 uint16_t m_dropped;
2393};
2394
2396 : TestCase ("Check correct behavior when a STA is receiving a transmission using an unsupported modulation"),
2397 m_dropped (0)
2398{
2399}
2400
2402{
2403}
2404
2405void
2408{
2409 // Print if the test is executed through test-runner
2410 if (reason == RXING)
2411 {
2412 std::cout << "Dropped a packet because already receiving" << std::endl;
2413 m_dropped++;
2414 }
2415}
2416
2417void
2419{
2420 uint16_t m_nStations = 2;
2421 NetDeviceContainer m_staDevices;
2422 NetDeviceContainer m_apDevices;
2423
2424 // RngSeedManager::SetSeed (1);
2425 // RngSeedManager::SetRun (40);
2426 int64_t streamNumber = 100;
2427
2429 wifiApNode.Create (1);
2430
2432 wifiStaNodes.Create (m_nStations);
2433
2434 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
2435 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
2436 spectrumChannel->AddPropagationLossModel (lossModel);
2438 CreateObject<ConstantSpeedPropagationDelayModel> ();
2439 spectrumChannel->SetPropagationDelayModel (delayModel);
2440
2442 phy.SetChannel (spectrumChannel);
2443
2444 Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (65535));
2445
2447 wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
2448
2450 mac.SetType ("ns3::StaWifiMac", "QosSupported", BooleanValue (true), "Ssid",
2451 SsidValue (Ssid ("non-existent-ssid")));
2452
2453 wifi.SetStandard (WIFI_STANDARD_80211ax);
2454 m_staDevices.Add (wifi.Install (phy, mac, wifiStaNodes.Get (0)));
2455 wifi.SetStandard (WIFI_STANDARD_80211ac);
2456 m_staDevices.Add (wifi.Install (phy, mac, wifiStaNodes.Get (1)));
2457
2458 wifi.SetStandard (WIFI_STANDARD_80211ax);
2459 mac.SetType ("ns3::ApWifiMac", "QosSupported", BooleanValue (true), "Ssid",
2460 SsidValue (Ssid ("wifi-backoff-ssid")), "BeaconInterval",
2461 TimeValue (MicroSeconds (102400)), "EnableBeaconJitter", BooleanValue (false));
2462
2463 m_apDevices = wifi.Install (phy, mac, wifiApNode);
2464
2465 // schedule association requests at different times
2466 Time init = MilliSeconds (100);
2468
2469 for (uint16_t i = 0; i < m_nStations; i++)
2470 {
2471 dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (i));
2472 Simulator::Schedule (init + i * MicroSeconds (102400), &WifiMac::SetSsid, dev->GetMac (),
2473 Ssid ("wifi-backoff-ssid"));
2474 }
2475
2476 // Assign fixed streams to random variables in use
2477 wifi.AssignStreams (m_apDevices, streamNumber);
2478
2480 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
2481
2482 positionAlloc->Add (Vector (0.0, 0.0, 0.0));
2483 positionAlloc->Add (Vector (1.0, 0.0, 0.0));
2484 positionAlloc->Add (Vector (0.0, 1.0, 0.0));
2485 positionAlloc->Add (Vector (-1.0, 0.0, 0.0));
2486 mobility.SetPositionAllocator (positionAlloc);
2487
2488 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
2489 mobility.Install (wifiApNode);
2490 mobility.Install (wifiStaNodes);
2491
2492 // set the TXOP limit on BE AC
2493 dev = DynamicCast<WifiNetDevice> (m_apDevices.Get (0));
2494 PointerValue ptr;
2495 dev->GetMac ()->GetAttribute ("BE_Txop", ptr);
2496
2497 PacketSocketHelper packetSocket;
2498 packetSocket.Install (wifiApNode);
2499 packetSocket.Install (wifiStaNodes);
2500
2501 // UL Traffic
2502 for (uint16_t i = 0; i < m_nStations; i++)
2503 {
2504 PacketSocketAddress socket;
2505 socket.SetSingleDevice (m_staDevices.Get (0)->GetIfIndex ());
2506 socket.SetPhysicalAddress (m_apDevices.Get (0)->GetAddress ());
2507 socket.SetProtocol (1);
2508 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
2509 client->SetAttribute ("PacketSize", UintegerValue (1500));
2510 client->SetAttribute ("MaxPackets", UintegerValue (200));
2511 client->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
2512 client->SetRemote (socket);
2513 wifiStaNodes.Get (i)->AddApplication (client);
2514 client->SetStartTime (MicroSeconds (400000));
2515 client->SetStopTime (Seconds (1.0));
2516 Ptr<PacketSocketClient> legacyStaClient = CreateObject<PacketSocketClient> ();
2517 legacyStaClient->SetAttribute ("PacketSize", UintegerValue (1500));
2518 legacyStaClient->SetAttribute ("MaxPackets", UintegerValue (200));
2519 legacyStaClient->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
2520 legacyStaClient->SetRemote (socket);
2521 wifiStaNodes.Get (i)->AddApplication (legacyStaClient);
2522 legacyStaClient->SetStartTime (MicroSeconds (400000));
2523 legacyStaClient->SetStopTime (Seconds (1.0));
2524 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
2525 server->SetLocal (socket);
2526 wifiApNode.Get (0)->AddApplication (server);
2527 server->SetStartTime (Seconds (0.0));
2528 server->SetStopTime (Seconds (1.0));
2529 }
2530
2531 // Trace dropped packets
2532 Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
2534
2535 Simulator::Stop (Seconds (1));
2536 Simulator::Run ();
2537
2538 CheckResults ();
2539
2540 Simulator::Destroy ();
2541}
2542
2543void
2545{
2546 NS_TEST_EXPECT_MSG_EQ (m_dropped, 0, "Dropped some packets unexpectedly");
2547}
2548
2556{
2557public:
2559};
2560
2562 : TestSuite ("wifi-phy-reception", UNIT)
2563{
2566 AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2567 AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2568 AddTestCase (new TestAmpduReception, TestCase::QUICK);
2569 AddTestCase (new TestUnsupportedModulationReception (), TestCase::QUICK);
2570}
2571
A-MPDU reception test.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void CheckRxDroppedBitmapAmpdu1(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
uint8_t m_rxFailureBitmapAmpdu1
bitmap of unsuccessfully received MPDUs in A-MPDU #1
void RxFailure(Ptr< WifiPsdu > psdu)
RX failure function.
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfully received MPDUs in A-MPDU #2
void DoRun(void) override
Implementation to actually run this TestCase.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
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 CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
uint8_t m_rxDroppedBitmapAmpdu1
bitmap of dropped MPDUs in A-MPDU #1
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
void ResetBitmaps()
Reset bitmaps function.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
Test PHY state upon success or failure of L-SIG and SIG-A.
void SendPacket(double rxPowerDbm)
Send packet function.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
uint64_t m_uid
the UID to use for the PPDU
void DoRun(void) override
Implementation to actually run this TestCase.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
Simple frame capture model test.
void Expect1000BPacketReceived()
Verify whether 1000 bytes packet has been received.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
void DoRun(void) override
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm, uint32_t packetSize)
Send packet function.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
bool m_rxSuccess1000B
count received packets with 1000B payload
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
bool m_rxSuccess1500B
count received packets with 1500B payload
void Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
uint64_t m_uid
the UID to use for the PPDU
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
bool m_rxDropped1000B
count dropped packets with 1000B payload
Preamble detection test w/o frame capture.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void SendPacket(double rxPowerDbm)
Send packet function.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void DoRun(void) override
Implementation to actually run this TestCase.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
Preamble detection test w/o frame capture.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void DoRun(void) override
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
Unsupported Modulation Reception Test This test creates a mixed network, in which an HE STA and a VHT...
void DoRun(void) override
Implementation to actually run this TestCase.
void Dropped(std::string context, Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Callback invoked when PHY drops an incoming packet.
void CheckResults(void)
Check correctness of transmitted frames.
uint16_t m_dropped
number of packets dropped by the AP because it was already receiving
wifi PHY reception Test Suite
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
keep track of a set of node pointers.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:364
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:294
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get(void) const
Definition: pointer.h:201
Make it easy to create and manage PHY objects for the spectrum model.
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:323
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
create MAC layers for a ns3::WifiNetDevice.
Ptr< WifiMac > GetMac(void) const
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:929
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:394
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:877
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1504
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:581
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:388
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:575
void SetOperatingChannel(uint8_t number, uint16_t frequency, uint16_t width)
Set the operating channel according to the specified parameters.
Definition: wifi-phy.cc:1067
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:877
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:2203
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:561
This objects implements the PHY state machine of the Wifi device.
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
std::vector< Ptr< WifiMacQueueItem > >::const_iterator end(void) const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:337
bool IsAggregate(void) const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:81
bool IsSingle(void) const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:75
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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:141
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:37
@ WIFI_MAC_QOSDATA
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
mac
Definition: third.py:99
wifi
Definition: third.py:96
wifiApNode
Definition: third.py:90
mobility
Definition: third.py:108
wifiStaNodes
Definition: third.py:88
phy
Definition: third.py:93
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:67
static const uint8_t CHANNEL_NUMBER
static const uint16_t GUARD_WIDTH
static const uint16_t CHANNEL_WIDTH
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
static const uint32_t FREQUENCY
WifiPhyState
The state of the PHY layer.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
@ IDLE
The PHY layer is IDLE.
static const uint32_t packetSize