1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2019 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
21 #include "ns3/log.h"
22 #include "ns3/test.h"
23 #include "ns3/node.h"
24 #include "ns3/pointer.h"
25 #include "ns3/string.h"
26 #include "ns3/simulator.h"
27 #include "ns3/rng-seed-manager.h"
28 #include "ns3/constant-position-mobility-model.h"
29 #include "ns3/wifi-spectrum-signal-parameters.h"
30 #include "ns3/wifi-spectrum-value-helper.h"
31 #include "ns3/multi-model-spectrum-channel.h"
32 #include "ns3/spectrum-wifi-phy.h"
33 #include "ns3/nist-error-rate-model.h"
34 #include "ns3/wifi-mac-header.h"
35 #include "ns3/wifi-net-device.h"
36 #include "ns3/wifi-psdu.h"
37 #include "ns3/he-ppdu.h"
38 #include "ns3/wifi-utils.h"
39 #include "ns3/ap-wifi-mac.h"
40 #include "ns3/sta-wifi-mac.h"
41 #include "ns3/he-configuration.h"
42 #include "ns3/ctrl-headers.h"
43 #include "ns3/threshold-preamble-detection-model.h"
44 #include "ns3/he-phy.h"
45 #include "ns3/waveform-generator.h"
46 #include "ns3/non-communicating-net-device.h"
47 #include "ns3/spectrum-wifi-helper.h"
48 #include "ns3/mobility-helper.h"
49
50 using namespace ns3;
51
52 NS_LOG_COMPONENT_DEFINE ("WifiPhyOfdmaTest");
53
54 static const uint8_t DEFAULT_CHANNEL_NUMBER = 36;
55 static const uint32_t DEFAULT_FREQUENCY = 5180; // MHz
56 static const WifiPhyBand DEFAULT_WIFI_BAND = WIFI_PHY_BAND_5GHZ;
57 static const uint16_t DEFAULT_CHANNEL_WIDTH = 20; // MHz
58 static const uint16_t DEFAULT_GUARD_WIDTH = DEFAULT_CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
59
60 /**
61 * HE PHY slightly modified so as to return a given
62 * STA-ID in case of DL MU for OfdmaSpectrumWifiPhy.
63 */
64 class OfdmaTestHePhy : public HePhy
65 {
66 public:
67 /**
68 * Constructor
69 *
70 * \param staId the ID of the STA to which this PHY belongs to
71 */
72 OfdmaTestHePhy (uint16_t staId);
73 virtual ~OfdmaTestHePhy ();
74
75 /**
76 * Return the STA ID that has been assigned to the station this PHY belongs to.
77 * This is typically called for MU PPDUs, in order to pick the correct PSDU.
78 *
79 * \param ppdu the PPDU for which the STA ID is requested
80 * \return the STA ID
81 */
82 uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
83
84 /**
85 * Set the global PPDU UID counter.
86 *
87 * \param uid the value to which the global PPDU UID counter should be set
88 */
89 void SetGlobalPpduUid (uint64_t uid);
90
91 private:
92 uint16_t m_staId; ///< ID of the STA to which this PHY belongs to
93 }; //class OfdmaTestHePhy
94
OfdmaTestHePhy(uint16_t staId)95 OfdmaTestHePhy::OfdmaTestHePhy (uint16_t staId)
96 : HePhy (),
97 m_staId (staId)
98 {
99 }
100
~OfdmaTestHePhy()101 OfdmaTestHePhy::~OfdmaTestHePhy ()
102 {
103 }
104
105 uint16_t
GetStaId(const Ptr<const WifiPpdu> ppdu) const106 OfdmaTestHePhy::GetStaId (const Ptr<const WifiPpdu> ppdu) const
107 {
108 if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
109 {
110 return m_staId;
111 }
112 return HePhy::GetStaId (ppdu);
113 }
114
115 void
SetGlobalPpduUid(uint64_t uid)116 OfdmaTestHePhy::SetGlobalPpduUid (uint64_t uid)
117 {
118 m_globalPpduUid = uid;
119 }
120
121 /**
122 * SpectrumWifiPhy used for testing OFDMA.
123 */
124 class OfdmaSpectrumWifiPhy : public SpectrumWifiPhy
125 {
126 public:
127 /**
128 * \brief Get the type ID.
129 * \return the object TypeId
130 */
131 static TypeId GetTypeId (void);
132 /**
133 * Constructor
134 *
135 * \param staId the ID of the STA to which this PHY belongs to
136 */
137 OfdmaSpectrumWifiPhy (uint16_t staId);
138 virtual ~OfdmaSpectrumWifiPhy ();
139
140 void DoInitialize (void) override;
141 void DoDispose (void) override;
142
143 using WifiPhy::Reset;
144
145 /**
146 * TracedCallback signature for UID of transmitted PPDU.
147 *
148 * \param uid the UID of the transmitted PPDU
149 */
150 typedef void (*TxPpduUidCallback)(uint64_t uid);
151
152 /**
153 * \param ppdu the PPDU to send
154 */
155 void StartTx (Ptr<WifiPpdu> ppdu) override;
156 /**
157 * \param currentChannelWidth channel width of the current transmission (MHz)
158 * \return the width of the guard band (MHz) set to 2
159 */
160 uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const override;
161
162 /**
163 * Set the global PPDU UID counter.
164 *
165 * \param uid the value to which the global PPDU UID counter should be set
166 */
167 void SetPpduUid (uint64_t uid);
168
169 /**
170 * Since we assume trigger frame was previously received from AP, this is used to set its UID
171 *
172 * \param uid the PPDU UID of the trigger frame
173 */
174 void SetTriggerFrameUid (uint64_t uid);
175
176 /**
177 * \return the current preamble events map
178 */
179 std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > & GetCurrentPreambleEvents (void);
180 /**
181 * \return the current event
182 */
183 Ptr<Event> GetCurrentEvent (void);
184
185 /**
186 * Wrapper to InterferenceHelper method.
187 *
188 * \param energyW the minimum energy (W) requested
189 * \param band identify the requested band
190 *
191 * \returns the expected amount of time the observed
192 * energy on the medium for a given band will
193 * be higher than the requested threshold.
194 */
195 Time GetEnergyDuration (double energyW, WifiSpectrumBand band);
196
197 /**
198 * \return a const pointer to the HE PHY instance
199 */
200 Ptr<const HePhy> GetHePhy (void) const;
201
202 private:
203 Ptr<OfdmaTestHePhy> m_ofdmTestHePhy; ///< Pointer to HE PHY instance used for OFDMA test
204 TracedCallback<uint64_t> m_phyTxPpduUidTrace; //!< Callback providing UID of the PPDU that is about to be transmitted
205 }; //class OfdmaSpectrumWifiPhy
206
207 TypeId
GetTypeId(void)208 OfdmaSpectrumWifiPhy::GetTypeId (void)
209 {
210 static TypeId tid = TypeId ("ns3::OfdmaSpectrumWifiPhy")
211 .SetParent<SpectrumWifiPhy> ()
212 .SetGroupName ("Wifi")
213 .AddTraceSource ("TxPpduUid",
214 "UID of the PPDU to be transmitted",
215 MakeTraceSourceAccessor (&OfdmaSpectrumWifiPhy::m_phyTxPpduUidTrace),
216 "ns3::OfdmaSpectrumWifiPhy::TxPpduUidCallback")
217 ;
218 return tid;
219 }
220
OfdmaSpectrumWifiPhy(uint16_t staId)221 OfdmaSpectrumWifiPhy::OfdmaSpectrumWifiPhy (uint16_t staId)
222 : SpectrumWifiPhy ()
223 {
224 m_ofdmTestHePhy = Create<OfdmaTestHePhy> (staId);
225 m_ofdmTestHePhy->SetOwner (this);
226 }
227
~OfdmaSpectrumWifiPhy()228 OfdmaSpectrumWifiPhy::~OfdmaSpectrumWifiPhy()
229 {
230 }
231
232 void
DoInitialize(void)233 OfdmaSpectrumWifiPhy::DoInitialize (void)
234 {
235 //Replace HE PHY instance with test instance
236 m_phyEntities[WIFI_MOD_CLASS_HE] = m_ofdmTestHePhy;
237 SpectrumWifiPhy::DoInitialize ();
238 }
239
240 void
DoDispose(void)241 OfdmaSpectrumWifiPhy::DoDispose (void)
242 {
243 m_ofdmTestHePhy = 0;
244 SpectrumWifiPhy::DoDispose ();
245 }
246
247 void
SetPpduUid(uint64_t uid)248 OfdmaSpectrumWifiPhy::SetPpduUid (uint64_t uid)
249 {
250 m_ofdmTestHePhy->SetGlobalPpduUid (uid);
251 m_previouslyRxPpduUid = uid;
252 }
253
254 void
SetTriggerFrameUid(uint64_t uid)255 OfdmaSpectrumWifiPhy::SetTriggerFrameUid (uint64_t uid)
256 {
257 m_previouslyRxPpduUid = uid;
258 }
259
260 void
StartTx(Ptr<WifiPpdu> ppdu)261 OfdmaSpectrumWifiPhy::StartTx (Ptr<WifiPpdu> ppdu)
262 {
263 m_phyTxPpduUidTrace (ppdu->GetUid ());
264 SpectrumWifiPhy::StartTx (ppdu);
265 }
266
267 std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > &
GetCurrentPreambleEvents(void)268 OfdmaSpectrumWifiPhy::GetCurrentPreambleEvents (void)
269 {
270 return m_currentPreambleEvents;
271 }
272
273 uint16_t
GetGuardBandwidth(uint16_t currentChannelWidth) const274 OfdmaSpectrumWifiPhy::GetGuardBandwidth (uint16_t currentChannelWidth) const
275 {
276 // return a small enough value to avoid having too much out of band transmission
277 // knowing that slopes are not configurable yet.
278 return 1;
279 }
280
281 Ptr<Event>
GetCurrentEvent(void)282 OfdmaSpectrumWifiPhy::GetCurrentEvent (void)
283 {
284 return m_currentEvent;
285 }
286
287 Time
GetEnergyDuration(double energyW,WifiSpectrumBand band)288 OfdmaSpectrumWifiPhy::GetEnergyDuration (double energyW, WifiSpectrumBand band)
289 {
290 return m_interference.GetEnergyDuration (energyW, band);
291 }
292
293 Ptr<const HePhy>
GetHePhy(void) const294 OfdmaSpectrumWifiPhy::GetHePhy (void) const
295 {
296 return DynamicCast<const HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
297 }
298
299 /**
300 * \ingroup wifi-test
301 * \ingroup tests
302 *
303 * \brief DL-OFDMA PHY test
304 */
305 class TestDlOfdmaPhyTransmission : public TestCase
306 {
307 public:
308 TestDlOfdmaPhyTransmission ();
309 virtual ~TestDlOfdmaPhyTransmission ();
310
311 private:
312 void DoSetup (void) override;
313 void DoTeardown (void) override;
314 void DoRun (void) override;
315
316 /**
317 * Receive success function for STA 1
318 * \param psdu the PSDU
319 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
320 * \param txVector the transmit vector
321 * \param statusPerMpdu reception status per MPDU
322 */
323 void RxSuccessSta1 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
324 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
325 /**
326 * Receive success function for STA 2
327 * \param psdu the PSDU
328 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
329 * \param txVector the transmit vector
330 * \param statusPerMpdu reception status per MPDU
331 */
332 void RxSuccessSta2 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
333 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
334 /**
335 * Receive success function for STA 3
336 * \param psdu the PSDU
337 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
338 * \param txVector the transmit vector
339 * \param statusPerMpdu reception status per MPDU
340 */
341 void RxSuccessSta3 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
342 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
343
344 /**
345 * Receive failure function for STA 1
346 * \param psdu the PSDU
347 */
348 void RxFailureSta1 (Ptr<WifiPsdu> psdu);
349 /**
350 * Receive failure function for STA 2
351 * \param psdu the PSDU
352 */
353 void RxFailureSta2 (Ptr<WifiPsdu> psdu);
354 /**
355 * Receive failure function for STA 3
356 * \param psdu the PSDU
357 */
358 void RxFailureSta3 (Ptr<WifiPsdu> psdu);
359
360 /**
361 * Check the results for STA 1
362 * \param expectedRxSuccess the expected number of RX success
363 * \param expectedRxFailure the expected number of RX failures
364 * \param expectedRxBytes the expected number of RX bytes
365 */
366 void CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
367 /**
368 * Check the results for STA 2
369 * \param expectedRxSuccess the expected number of RX success
370 * \param expectedRxFailure the expected number of RX failures
371 * \param expectedRxBytes the expected number of RX bytes
372 */
373 void CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
374 /**
375 * Check the results for STA 3
376 * \param expectedRxSuccess the expected number of RX success
377 * \param expectedRxFailure the expected number of RX failures
378 * \param expectedRxBytes the expected number of RX bytes
379 */
380 void CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
381
382 /**
383 * Reset the results
384 */
385 void ResetResults ();
386
387 /**
388 * Send MU-PPDU function
389 * \param rxStaId1 the ID of the recipient STA for the first PSDU
390 * \param rxStaId2 the ID of the recipient STA for the second PSDU
391 */
392 void SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2);
393
394 /**
395 * Generate interference function
396 * \param interferencePsd the PSD of the interference to be generated
397 * \param duration the duration of the interference
398 */
399 void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
400 /**
401 * Stop interference function
402 */
403 void StopInterference (void);
404
405 /**
406 * Run one function
407 */
408 void RunOne ();
409
410 /**
411 * Schedule now to check the PHY state
412 * \param phy the PHY
413 * \param expectedState the expected state of the PHY
414 */
415 void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
416 /**
417 * Check the PHY state now
418 * \param phy the PHY
419 * \param expectedState the expected state of the PHY
420 */
421 void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
422
423 uint32_t m_countRxSuccessSta1; ///< count RX success for STA 1
424 uint32_t m_countRxSuccessSta2; ///< count RX success for STA 2
425 uint32_t m_countRxSuccessSta3; ///< count RX success for STA 3
426 uint32_t m_countRxFailureSta1; ///< count RX failure for STA 1
427 uint32_t m_countRxFailureSta2; ///< count RX failure for STA 2
428 uint32_t m_countRxFailureSta3; ///< count RX failure for STA 3
429 uint32_t m_countRxBytesSta1; ///< count RX bytes for STA 1
430 uint32_t m_countRxBytesSta2; ///< count RX bytes for STA 2
431 uint32_t m_countRxBytesSta3; ///< count RX bytes for STA 3
432
433 Ptr<SpectrumWifiPhy> m_phyAp; ///< PHY of AP
434 Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
435 Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
436 Ptr<OfdmaSpectrumWifiPhy> m_phySta3; ///< PHY of STA 3
437 Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
438
439 uint16_t m_frequency; ///< frequency in MHz
440 uint16_t m_channelWidth; ///< channel width in MHz
441 Time m_expectedPpduDuration; ///< expected duration to send MU PPDU
442 };
443
TestDlOfdmaPhyTransmission()444 TestDlOfdmaPhyTransmission::TestDlOfdmaPhyTransmission ()
445 : TestCase ("DL-OFDMA PHY test"),
446 m_countRxSuccessSta1 (0),
447 m_countRxSuccessSta2 (0),
448 m_countRxSuccessSta3 (0),
449 m_countRxFailureSta1 (0),
450 m_countRxFailureSta2 (0),
451 m_countRxFailureSta3 (0),
452 m_countRxBytesSta1 (0),
453 m_countRxBytesSta2 (0),
454 m_countRxBytesSta3 (0),
455 m_frequency (DEFAULT_FREQUENCY),
456 m_channelWidth (DEFAULT_CHANNEL_WIDTH),
457 m_expectedPpduDuration (NanoSeconds (306400))
458 {
459 }
460
461 void
ResetResults(void)462 TestDlOfdmaPhyTransmission::ResetResults (void)
463 {
464 m_countRxSuccessSta1 = 0;
465 m_countRxSuccessSta2 = 0;
466 m_countRxSuccessSta3 = 0;
467 m_countRxFailureSta1 = 0;
468 m_countRxFailureSta2 = 0;
469 m_countRxFailureSta3 = 0;
470 m_countRxBytesSta1 = 0;
471 m_countRxBytesSta2 = 0;
472 m_countRxBytesSta3 = 0;
473 }
474
475 void
SendMuPpdu(uint16_t rxStaId1,uint16_t rxStaId2)476 TestDlOfdmaPhyTransmission::SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2)
477 {
478 NS_LOG_FUNCTION (this << rxStaId1 << rxStaId2);
479 WifiConstPsduMap psdus;
480 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, m_channelWidth, false, false);
481 HeRu::RuType ruType = HeRu::RU_106_TONE;
482 if (m_channelWidth == 20)
483 {
484 ruType = HeRu::RU_106_TONE;
485 }
486 else if (m_channelWidth == 40)
487 {
488 ruType = HeRu::RU_242_TONE;
489 }
490 else if (m_channelWidth == 80)
491 {
492 ruType = HeRu::RU_484_TONE;
493 }
494 else if (m_channelWidth == 160)
495 {
496 ruType = HeRu::RU_996_TONE;
497 }
498 else
499 {
500 NS_ASSERT_MSG (false, "Unsupported channel width");
501 }
502
503 HeRu::RuSpec ru1 (ruType, 1, true);
504 txVector.SetRu (ru1, rxStaId1);
505 txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
506 txVector.SetNss (1, rxStaId1);
507
508 HeRu::RuSpec ru2 (ruType, (m_channelWidth == 160 ? 1 : 2), (m_channelWidth == 160 ? false : true));
509 txVector.SetRu (ru2, rxStaId2);
510 txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
511 txVector.SetNss (1, rxStaId2);
512
513 Ptr<Packet> pkt1 = Create<Packet> (1000);
514 WifiMacHeader hdr1;
515 hdr1.SetType (WIFI_MAC_QOSDATA);
516 hdr1.SetQosTid (0);
517 hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
518 hdr1.SetSequenceNumber (1);
519 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
520 psdus.insert (std::make_pair (rxStaId1, psdu1));
521
522 Ptr<Packet> pkt2 = Create<Packet> (1500);
523 WifiMacHeader hdr2;
524 hdr2.SetType (WIFI_MAC_QOSDATA);
525 hdr2.SetQosTid (0);
526 hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
527 hdr2.SetSequenceNumber (2);
528 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
529 psdus.insert (std::make_pair (rxStaId2, psdu2));
530
531 m_phyAp->Send (psdus, txVector);
532 }
533
534 void
GenerateInterference(Ptr<SpectrumValue> interferencePsd,Time duration)535 TestDlOfdmaPhyTransmission::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
536 {
537 m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
538 m_phyInterferer->SetPeriod (duration);
539 m_phyInterferer->Start ();
540 Simulator::Schedule (duration, &TestDlOfdmaPhyTransmission::StopInterference, this);
541 }
542
543 void
StopInterference(void)544 TestDlOfdmaPhyTransmission::StopInterference (void)
545 {
546 m_phyInterferer->Stop();
547 }
548
~TestDlOfdmaPhyTransmission()549 TestDlOfdmaPhyTransmission::~TestDlOfdmaPhyTransmission ()
550 {
551 }
552
553 void
RxSuccessSta1(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)554 TestDlOfdmaPhyTransmission::RxSuccessSta1 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
555 WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
556 {
557 NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
558 m_countRxSuccessSta1++;
559 m_countRxBytesSta1 += (psdu->GetSize () - 30);
560 }
561
562 void
RxSuccessSta2(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)563 TestDlOfdmaPhyTransmission::RxSuccessSta2 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
564 WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
565 {
566 NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
567 m_countRxSuccessSta2++;
568 m_countRxBytesSta2 += (psdu->GetSize () - 30);
569 }
570
571 void
RxSuccessSta3(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)572 TestDlOfdmaPhyTransmission::RxSuccessSta3 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
573 WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
574 {
575 NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
576 m_countRxSuccessSta3++;
577 m_countRxBytesSta3 += (psdu->GetSize () - 30);
578 }
579
580 void
RxFailureSta1(Ptr<WifiPsdu> psdu)581 TestDlOfdmaPhyTransmission::RxFailureSta1 (Ptr<WifiPsdu> psdu)
582 {
583 NS_LOG_FUNCTION (this << *psdu);
584 m_countRxFailureSta1++;
585 }
586
587 void
RxFailureSta2(Ptr<WifiPsdu> psdu)588 TestDlOfdmaPhyTransmission::RxFailureSta2 (Ptr<WifiPsdu> psdu)
589 {
590 NS_LOG_FUNCTION (this << *psdu);
591 m_countRxFailureSta2++;
592 }
593
594 void
RxFailureSta3(Ptr<WifiPsdu> psdu)595 TestDlOfdmaPhyTransmission::RxFailureSta3 (Ptr<WifiPsdu> psdu)
596 {
597 NS_LOG_FUNCTION (this << *psdu);
598 m_countRxFailureSta3++;
599 }
600
601 void
CheckResultsSta1(uint32_t expectedRxSuccess,uint32_t expectedRxFailure,uint32_t expectedRxBytes)602 TestDlOfdmaPhyTransmission::CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
603 {
604 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta1, expectedRxSuccess, "The number of successfully received packets by STA 1 is not correct!");
605 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta1, expectedRxFailure, "The number of unsuccessfully received packets by STA 1 is not correct!");
606 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta1, expectedRxBytes, "The number of bytes received by STA 1 is not correct!");
607 }
608
609 void
CheckResultsSta2(uint32_t expectedRxSuccess,uint32_t expectedRxFailure,uint32_t expectedRxBytes)610 TestDlOfdmaPhyTransmission::CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
611 {
612 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta2, expectedRxSuccess, "The number of successfully received packets by STA 2 is not correct!");
613 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta2, expectedRxFailure, "The number of unsuccessfully received packets by STA 2 is not correct!");
614 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta2, expectedRxBytes, "The number of bytes received by STA 2 is not correct!");
615 }
616
617 void
CheckResultsSta3(uint32_t expectedRxSuccess,uint32_t expectedRxFailure,uint32_t expectedRxBytes)618 TestDlOfdmaPhyTransmission::CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
619 {
620 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta3, expectedRxSuccess, "The number of successfully received packets by STA 3 is not correct!");
621 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta3, expectedRxFailure, "The number of unsuccessfully received packets by STA 3 is not correct!");
622 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta3, expectedRxBytes, "The number of bytes received by STA 3 is not correct!");
623 }
624
625 void
CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)626 TestDlOfdmaPhyTransmission::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
627 {
628 //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
629 Simulator::ScheduleNow (&TestDlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
630 }
631
632 void
DoCheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)633 TestDlOfdmaPhyTransmission::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
634 {
635 WifiPhyState currentState;
636 PointerValue ptr;
637 phy->GetAttribute ("State", ptr);
638 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
639 currentState = state->GetState ();
640 NS_LOG_FUNCTION (this << currentState);
641 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
642 }
643
644 void
DoSetup(void)645 TestDlOfdmaPhyTransmission::DoSetup (void)
646 {
647 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
648 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
649 lossModel->SetFrequency (m_frequency * 1e6);
650 spectrumChannel->AddPropagationLossModel (lossModel);
651 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
652 spectrumChannel->SetPropagationDelayModel (delayModel);
653
654 Ptr<Node> apNode = CreateObject<Node> ();
655 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
656 m_phyAp = CreateObject<SpectrumWifiPhy> ();
657 m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
658 m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
659 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
660 m_phyAp->SetErrorRateModel (error);
661 m_phyAp->SetDevice (apDev);
662 m_phyAp->SetChannel (spectrumChannel);
663 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
664 m_phyAp->SetMobility (apMobility);
665 apDev->SetPhy (m_phyAp);
666 apNode->AggregateObject (apMobility);
667 apNode->AddDevice (apDev);
668
669 Ptr<Node> sta1Node = CreateObject<Node> ();
670 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
671 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
672 m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
673 m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
674 m_phySta1->SetErrorRateModel (error);
675 m_phySta1->SetDevice (sta1Dev);
676 m_phySta1->SetChannel (spectrumChannel);
677 m_phySta1->SetReceiveOkCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxSuccessSta1, this));
678 m_phySta1->SetReceiveErrorCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxFailureSta1, this));
679 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
680 m_phySta1->SetMobility (sta1Mobility);
681 sta1Dev->SetPhy (m_phySta1);
682 sta1Node->AggregateObject (sta1Mobility);
683 sta1Node->AddDevice (sta1Dev);
684
685 Ptr<Node> sta2Node = CreateObject<Node> ();
686 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
687 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
688 m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
689 m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
690 m_phySta2->SetErrorRateModel (error);
691 m_phySta2->SetDevice (sta2Dev);
692 m_phySta2->SetChannel (spectrumChannel);
693 m_phySta2->SetReceiveOkCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxSuccessSta2, this));
694 m_phySta2->SetReceiveErrorCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxFailureSta2, this));
695 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
696 m_phySta2->SetMobility (sta2Mobility);
697 sta2Dev->SetPhy (m_phySta2);
698 sta2Node->AggregateObject (sta2Mobility);
699 sta2Node->AddDevice (sta2Dev);
700
701 Ptr<Node> sta3Node = CreateObject<Node> ();
702 Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
703 m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
704 m_phySta3->CreateWifiSpectrumPhyInterface (sta3Dev);
705 m_phySta3->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
706 m_phySta3->SetErrorRateModel (error);
707 m_phySta3->SetDevice (sta3Dev);
708 m_phySta3->SetChannel (spectrumChannel);
709 m_phySta3->SetReceiveOkCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxSuccessSta3, this));
710 m_phySta3->SetReceiveErrorCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxFailureSta3, this));
711 Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
712 m_phySta3->SetMobility (sta3Mobility);
713 sta3Dev->SetPhy (m_phySta3);
714 sta3Node->AggregateObject (sta3Mobility);
715 sta3Node->AddDevice (sta3Dev);
716
717 Ptr<Node> interfererNode = CreateObject<Node> ();
718 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
719 m_phyInterferer = CreateObject<WaveformGenerator> ();
720 m_phyInterferer->SetDevice (interfererDev);
721 m_phyInterferer->SetChannel (spectrumChannel);
722 m_phyInterferer->SetDutyCycle (1);
723 interfererNode->AddDevice (interfererDev);
724 }
725
726 void
DoTeardown(void)727 TestDlOfdmaPhyTransmission::DoTeardown (void)
728 {
729 m_phyAp->Dispose ();
730 m_phyAp = 0;
731 m_phySta1->Dispose ();
732 m_phySta1 = 0;
733 m_phySta2->Dispose ();
734 m_phySta2 = 0;
735 m_phySta3->Dispose ();
736 m_phySta3 = 0;
737 m_phyInterferer->Dispose ();
738 m_phyInterferer = 0;
739 }
740
741 void
RunOne(void)742 TestDlOfdmaPhyTransmission::RunOne (void)
743 {
744 RngSeedManager::SetSeed (1);
745 RngSeedManager::SetRun (1);
746 int64_t streamNumber = 0;
747 m_phyAp->AssignStreams (streamNumber);
748 m_phySta1->AssignStreams (streamNumber);
749 m_phySta2->AssignStreams (streamNumber);
750 m_phySta3->AssignStreams (streamNumber);
751
752 m_phyAp->SetFrequency (m_frequency);
753 m_phyAp->SetChannelWidth (m_channelWidth);
754
755 m_phySta1->SetFrequency (m_frequency);
756 m_phySta1->SetChannelWidth (m_channelWidth);
757
758 m_phySta2->SetFrequency (m_frequency);
759 m_phySta2->SetChannelWidth (m_channelWidth);
760
761 m_phySta3->SetFrequency (m_frequency);
762 m_phySta3->SetChannelWidth (m_channelWidth);
763
764 Simulator::Schedule (Seconds (0.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
765
766 //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
767 //Each STA should receive its PSDU.
768 Simulator::Schedule (Seconds (1.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
769
770 //Since it takes m_expectedPpduDuration to transmit the PPDU,
771 //all 3 PHYs should be back to IDLE at the same time,
772 //even the PHY that has no PSDU addressed to it.
773 Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
774 Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
775 Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
776 Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::IDLE);
777 Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::IDLE);
778 Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::IDLE);
779
780 //One PSDU of 1000 bytes should have been successfully received by STA 1
781 Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
782 //One PSDU of 1500 bytes should have been successfully received by STA 2
783 Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
784 //No PSDU should have been received by STA 3
785 Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
786
787 Simulator::Schedule (Seconds (1.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
788
789 //Send MU PPDU with two PSDUs addressed to STA 1 and STA 3:
790 //STA 1 should receive its PSDU, whereas STA 2 should not receive any PSDU
791 //but should keep its PHY busy during all PPDU duration.
792 Simulator::Schedule (Seconds (2.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 3);
793
794 //Since it takes m_expectedPpduDuration to transmit the PPDU,
795 //all 3 PHYs should be back to IDLE at the same time,
796 //even the PHY that has no PSDU addressed to it.
797 Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
798 Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::CCA_BUSY);
799 Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::RX);
800 Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::IDLE);
801 Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::IDLE);
802 Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::IDLE);
803
804 //One PSDU of 1000 bytes should have been successfully received by STA 1
805 Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
806 //No PSDU should have been received by STA 2
807 Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 0, 0);
808 //One PSDU of 1500 bytes should have been successfully received by STA 3
809 Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 1, 0, 1500);
810
811 Simulator::Schedule (Seconds (2.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
812
813 //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
814 Simulator::Schedule (Seconds (3.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
815
816 //A strong non-wifi interference is generated on RU 1 during PSDU reception
817 BandInfo bandInfo;
818 bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
819 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
820 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
821 Bands bands;
822 bands.push_back (bandInfo);
823
824 Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
825 Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
826 double interferencePower = 0.1; //watts
827 *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
828
829 Simulator::Schedule (Seconds (3.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
830
831 //Since it takes m_expectedPpduDuration to transmit the PPDU,
832 //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
833 //even the PHY that has no PSDU addressed to it.
834 Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
835 Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
836 Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
837 Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::CCA_BUSY);
838 Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::CCA_BUSY);
839 Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
840
841 //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
842 Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
843 //One PSDU of 1500 bytes should have been successfully received by STA 2
844 Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
845 //No PSDU should have been received by STA3
846 Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
847
848 Simulator::Schedule (Seconds (3.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
849
850 //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
851 Simulator::Schedule (Seconds (4.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
852
853 //A strong non-wifi interference is generated on RU 2 during PSDU reception
854 bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
855 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
856 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
857 bands.clear ();
858 bands.push_back (bandInfo);
859
860 Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
861 Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
862 *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
863
864 Simulator::Schedule (Seconds (4.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
865
866 //Since it takes m_expectedPpduDuration to transmit the PPDU,
867 //both PHYs should be back to IDLE (or CCA_BUSY if interference on the primary 20 MHz) at the same time,
868 //even the PHY that has no PSDU addressed to it.
869 Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
870 Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
871 Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
872 Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
873 Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
874 Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
875
876 //One PSDU of 1000 bytes should have been successfully received by STA 1
877 Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
878 //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
879 Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
880 //No PSDU should have been received by STA3
881 Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
882
883 Simulator::Schedule (Seconds (4.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
884
885 //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
886 Simulator::Schedule (Seconds (5.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
887
888 //A strong non-wifi interference is generated on the full band during PSDU reception
889 bandInfo.fc = m_frequency * 1e6;
890 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
891 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
892 bands.clear ();
893 bands.push_back (bandInfo);
894
895 Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
896 Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
897 *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
898
899 Simulator::Schedule (Seconds (5.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
900
901 //Since it takes m_expectedPpduDuration to transmit the PPDU,
902 //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
903 //even the PHY that has no PSDU addressed to it.
904 Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
905 Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
906 Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
907 Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::CCA_BUSY);
908 Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::CCA_BUSY);
909 Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
910
911 //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
912 Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
913 //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
914 Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
915 //No PSDU should have been received by STA3
916 Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
917
918 Simulator::Schedule (Seconds (5.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
919
920 Simulator::Run ();
921 }
922
923 void
DoRun(void)924 TestDlOfdmaPhyTransmission::DoRun (void)
925 {
926 m_frequency = 5180;
927 m_channelWidth = 20;
928 m_expectedPpduDuration = NanoSeconds (306400);
929 RunOne ();
930
931 m_frequency = 5190;
932 m_channelWidth = 40;
933 m_expectedPpduDuration = NanoSeconds (156800);
934 RunOne ();
935
936 m_frequency = 5210;
937 m_channelWidth = 80;
938 m_expectedPpduDuration = NanoSeconds (102400);
939 RunOne ();
940
941 m_frequency = 5250;
942 m_channelWidth = 160;
943 m_expectedPpduDuration = NanoSeconds (75200);
944 RunOne ();
945
946 Simulator::Destroy ();
947 }
948
949
950 /**
951 * \ingroup wifi-test
952 * \ingroup tests
953 *
954 * \brief UL-OFDMA PPDU UID attribution test
955 */
956 class TestUlOfdmaPpduUid : public TestCase
957 {
958 public:
959 TestUlOfdmaPpduUid ();
960 virtual ~TestUlOfdmaPpduUid ();
961
962 private:
963 void DoSetup (void) override;
964 void DoTeardown (void) override;
965 void DoRun (void) override;
966
967 /**
968 * Transmitted PPDU information function for AP
969 * \param uid the UID of the transmitted PPDU
970 */
971 void TxPpduAp (uint64_t uid);
972 /**
973 * Transmitted PPDU information function for STA 1
974 * \param uid the UID of the transmitted PPDU
975 */
976 void TxPpduSta1 (uint64_t uid);
977 /**
978 * Transmitted PPDU information function for STA 2
979 * \param uid the UID of the transmitted PPDU
980 */
981 void TxPpduSta2 (uint64_t uid);
982 /**
983 * Reset the global PPDU UID counter in WifiPhy
984 */
985 void ResetPpduUid (void);
986
987 /**
988 * Send MU-PPDU toward both STAs.
989 */
990 void SendMuPpdu (void);
991 /**
992 * Send TB-PPDU from both STAs.
993 */
994 void SendTbPpdu (void);
995 /**
996 * Send SU-PPDU function
997 * \param txStaId the ID of the sending STA
998 */
999 void SendSuPpdu (uint16_t txStaId);
1000
1001 /**
1002 * Check the UID of the transmitted PPDU
1003 * \param staId the STA-ID of the PHY (0 for AP)
1004 * \param expectedUid the expected UID
1005 */
1006 void CheckUid (uint16_t staId, uint64_t expectedUid);
1007
1008 Ptr<OfdmaSpectrumWifiPhy> m_phyAp; ///< PHY of AP
1009 Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
1010 Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
1011
1012 uint64_t m_ppduUidAp; ///< UID of PPDU transmitted by AP
1013 uint64_t m_ppduUidSta1; ///< UID of PPDU transmitted by STA1
1014 uint64_t m_ppduUidSta2; ///< UID of PPDU transmitted by STA2
1015 };
1016
TestUlOfdmaPpduUid()1017 TestUlOfdmaPpduUid::TestUlOfdmaPpduUid ()
1018 : TestCase ("UL-OFDMA PPDU UID attribution test"),
1019 m_ppduUidAp (UINT64_MAX),
1020 m_ppduUidSta1 (UINT64_MAX),
1021 m_ppduUidSta2 (UINT64_MAX)
1022 {
1023 }
1024
~TestUlOfdmaPpduUid()1025 TestUlOfdmaPpduUid::~TestUlOfdmaPpduUid ()
1026 {
1027 }
1028
1029 void
DoSetup(void)1030 TestUlOfdmaPpduUid::DoSetup (void)
1031 {
1032 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
1033 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
1034 lossModel->SetFrequency (DEFAULT_FREQUENCY);
1035 spectrumChannel->AddPropagationLossModel (lossModel);
1036 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
1037 spectrumChannel->SetPropagationDelayModel (delayModel);
1038
1039 Ptr<Node> apNode = CreateObject<Node> ();
1040 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
1041 m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
1042 m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
1043 m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1044 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1045 m_phyAp->SetErrorRateModel (error);
1046 m_phyAp->SetFrequency (DEFAULT_FREQUENCY);
1047 m_phyAp->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1048 m_phyAp->SetDevice (apDev);
1049 m_phyAp->SetChannel (spectrumChannel);
1050 m_phyAp->TraceConnectWithoutContext ("TxPpduUid", MakeCallback (&TestUlOfdmaPpduUid::TxPpduAp, this));
1051 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
1052 m_phyAp->SetMobility (apMobility);
1053 apDev->SetPhy (m_phyAp);
1054 apNode->AggregateObject (apMobility);
1055 apNode->AddDevice (apDev);
1056
1057 Ptr<Node> sta1Node = CreateObject<Node> ();
1058 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
1059 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
1060 m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
1061 m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1062 m_phySta1->SetErrorRateModel (error);
1063 m_phySta1->SetFrequency (DEFAULT_FREQUENCY);
1064 m_phySta1->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1065 m_phySta1->SetDevice (sta1Dev);
1066 m_phySta1->SetChannel (spectrumChannel);
1067 m_phySta1->TraceConnectWithoutContext ("TxPpduUid", MakeCallback (&TestUlOfdmaPpduUid::TxPpduSta1, this));
1068 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
1069 m_phySta1->SetMobility (sta1Mobility);
1070 sta1Dev->SetPhy (m_phySta1);
1071 sta1Node->AggregateObject (sta1Mobility);
1072 sta1Node->AddDevice (sta1Dev);
1073
1074 Ptr<Node> sta2Node = CreateObject<Node> ();
1075 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
1076 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
1077 m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
1078 m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1079 m_phySta2->SetErrorRateModel (error);
1080 m_phySta2->SetFrequency (DEFAULT_FREQUENCY);
1081 m_phySta2->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1082 m_phySta2->SetDevice (sta2Dev);
1083 m_phySta2->SetChannel (spectrumChannel);
1084 m_phySta2->TraceConnectWithoutContext ("TxPpduUid", MakeCallback (&TestUlOfdmaPpduUid::TxPpduSta2, this));
1085 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
1086 m_phySta2->SetMobility (sta2Mobility);
1087 sta2Dev->SetPhy (m_phySta2);
1088 sta2Node->AggregateObject (sta2Mobility);
1089 sta2Node->AddDevice (sta2Dev);
1090 }
1091
1092 void
DoTeardown(void)1093 TestUlOfdmaPpduUid::DoTeardown (void)
1094 {
1095 m_phyAp->Dispose ();
1096 m_phyAp = 0;
1097 m_phySta1->Dispose ();
1098 m_phySta1 = 0;
1099 m_phySta2->Dispose ();
1100 m_phySta2 = 0;
1101 }
1102
1103 void
CheckUid(uint16_t staId,uint64_t expectedUid)1104 TestUlOfdmaPpduUid::CheckUid (uint16_t staId, uint64_t expectedUid)
1105 {
1106 uint64_t uid;
1107 std::string device;
1108 switch (staId)
1109 {
1110 case 0:
1111 uid = m_ppduUidAp;
1112 device = "AP";
1113 break;
1114 case 1:
1115 uid = m_ppduUidSta1;
1116 device = "STA1";
1117 break;
1118 case 2:
1119 uid = m_ppduUidSta2;
1120 device = "STA2";
1121 break;
1122 default:
1123 NS_ABORT_MSG ("Unexpected STA-ID");
1124 }
1125 NS_TEST_ASSERT_MSG_EQ (uid, expectedUid, "UID " << uid << " does not match expected one " << expectedUid << " for " << device << " at " << Simulator::Now ());
1126 }
1127
1128 void
TxPpduAp(uint64_t uid)1129 TestUlOfdmaPpduUid::TxPpduAp (uint64_t uid)
1130 {
1131 NS_LOG_FUNCTION (this << uid);
1132 m_ppduUidAp = uid;
1133 }
1134
1135 void
TxPpduSta1(uint64_t uid)1136 TestUlOfdmaPpduUid::TxPpduSta1 (uint64_t uid)
1137 {
1138 NS_LOG_FUNCTION (this << uid);
1139 m_ppduUidSta1 = uid;
1140 }
1141
1142 void
TxPpduSta2(uint64_t uid)1143 TestUlOfdmaPpduUid::TxPpduSta2 (uint64_t uid)
1144 {
1145 NS_LOG_FUNCTION (this << uid);
1146 m_ppduUidSta2 = uid;
1147 }
1148
1149 void
ResetPpduUid(void)1150 TestUlOfdmaPpduUid::ResetPpduUid (void)
1151 {
1152 NS_LOG_FUNCTION (this);
1153 m_phyAp->SetPpduUid (0); //one is enough since it's a global attribute
1154 return;
1155 }
1156
1157 void
SendMuPpdu(void)1158 TestUlOfdmaPpduUid::SendMuPpdu (void)
1159 {
1160 WifiConstPsduMap psdus;
1161 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1162
1163 uint16_t rxStaId1 = 1;
1164 HeRu::RuSpec ru1 (HeRu::RU_106_TONE, 1, false);
1165 txVector.SetRu (ru1, rxStaId1);
1166 txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
1167 txVector.SetNss (1, rxStaId1);
1168
1169 uint16_t rxStaId2 = 2;
1170 HeRu::RuSpec ru2 (HeRu::RU_106_TONE, 2, false);
1171 txVector.SetRu (ru2, rxStaId2);
1172 txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
1173 txVector.SetNss (1, rxStaId2);
1174
1175 Ptr<Packet> pkt1 = Create<Packet> (1000);
1176 WifiMacHeader hdr1;
1177 hdr1.SetType (WIFI_MAC_QOSDATA);
1178 hdr1.SetQosTid (0);
1179 hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
1180 hdr1.SetSequenceNumber (1);
1181 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
1182 psdus.insert (std::make_pair (rxStaId1, psdu1));
1183
1184 Ptr<Packet> pkt2 = Create<Packet> (1500);
1185 WifiMacHeader hdr2;
1186 hdr2.SetType (WIFI_MAC_QOSDATA);
1187 hdr2.SetQosTid (0);
1188 hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
1189 hdr2.SetSequenceNumber (2);
1190 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
1191 psdus.insert (std::make_pair (rxStaId2, psdu2));
1192
1193 m_phyAp->Send (psdus, txVector);
1194 }
1195
1196 void
SendTbPpdu(void)1197 TestUlOfdmaPpduUid::SendTbPpdu (void)
1198 {
1199 WifiConstPsduMap psdus1;
1200 WifiConstPsduMap psdus2;
1201 WifiTxVector txVector1 = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1202 WifiTxVector txVector2 = txVector1;
1203
1204 uint16_t rxStaId1 = 1;
1205 HeRu::RuSpec ru1 (HeRu::RU_106_TONE, 1, false);
1206 txVector1.SetRu (ru1, rxStaId1);
1207 txVector1.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
1208 txVector1.SetNss (1, rxStaId1);
1209
1210 Ptr<Packet> pkt1 = Create<Packet> (1000);
1211 WifiMacHeader hdr1;
1212 hdr1.SetType (WIFI_MAC_QOSDATA);
1213 hdr1.SetQosTid (0);
1214 hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1215 hdr1.SetSequenceNumber (1);
1216 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
1217 psdus1.insert (std::make_pair (rxStaId1, psdu1));
1218
1219 uint16_t rxStaId2 = 2;
1220 HeRu::RuSpec ru2 (HeRu::RU_106_TONE, 2, false);
1221 txVector2.SetRu (ru2, rxStaId2);
1222 txVector2.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
1223 txVector2.SetNss (1, rxStaId2);
1224
1225 Ptr<Packet> pkt2 = Create<Packet> (1500);
1226 WifiMacHeader hdr2;
1227 hdr2.SetType (WIFI_MAC_QOSDATA);
1228 hdr2.SetQosTid (0);
1229 hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1230 hdr2.SetSequenceNumber (2);
1231 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
1232 psdus2.insert (std::make_pair (rxStaId2, psdu2));
1233
1234 Time txDuration1 = m_phySta1->CalculateTxDuration (psdu1->GetSize (), txVector1,
1235 m_phySta1->GetPhyBand (), rxStaId1);
1236 Time txDuration2 = m_phySta2->CalculateTxDuration (psdu2->GetSize (), txVector2,
1237 m_phySta1->GetPhyBand (), rxStaId2);
1238 Time txDuration = std::max (txDuration1, txDuration2);
1239
1240 txVector1.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta1->GetPhyBand ()));
1241 txVector2.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta2->GetPhyBand ()));
1242
1243 m_phySta1->Send (psdus1, txVector1);
1244 m_phySta2->Send (psdus2, txVector2);
1245 }
1246
1247 void
SendSuPpdu(uint16_t txStaId)1248 TestUlOfdmaPpduUid::SendSuPpdu (uint16_t txStaId)
1249 {
1250 WifiConstPsduMap psdus;
1251 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1252
1253 Ptr<Packet> pkt = Create<Packet> (1000);
1254 WifiMacHeader hdr;
1255 hdr.SetType (WIFI_MAC_QOSDATA);
1256 hdr.SetQosTid (0);
1257 hdr.SetAddr1 (Mac48Address::GetBroadcast ());
1258 hdr.SetSequenceNumber (1);
1259 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1260 psdus.insert (std::make_pair (SU_STA_ID, psdu));
1261
1262 switch (txStaId)
1263 {
1264 case 0:
1265 m_phyAp->Send (psdus, txVector);
1266 break;
1267 case 1:
1268 m_phySta1->Send (psdus, txVector);
1269 break;
1270 case 2:
1271 m_phySta2->Send (psdus, txVector);
1272 break;
1273 default:
1274 NS_ABORT_MSG ("Unexpected STA-ID");
1275 }
1276 }
1277
1278 void
DoRun(void)1279 TestUlOfdmaPpduUid::DoRun (void)
1280 {
1281 RngSeedManager::SetSeed (1);
1282 RngSeedManager::SetRun (1);
1283 int64_t streamNumber = 0;
1284 m_phyAp->AssignStreams (streamNumber);
1285 m_phySta1->AssignStreams (streamNumber);
1286 m_phySta2->AssignStreams (streamNumber);
1287
1288 //Reset PPDU UID so as not to be dependent on previously executed test cases,
1289 //since global attribute will be changed).
1290 ResetPpduUid ();
1291
1292 //Send HE MU PPDU with two PSDUs addressed to STA 1 and STA 2.
1293 //PPDU UID should be equal to 0 (the first counter value).
1294 Simulator::Schedule (Seconds (1.0), &TestUlOfdmaPpduUid::SendMuPpdu, this);
1295 Simulator::Schedule (Seconds (1.0), &TestUlOfdmaPpduUid::CheckUid, this, 0, 0);
1296
1297 //Send HE SU PPDU from AP.
1298 //PPDU UID should be incremented since this is a new PPDU.
1299 Simulator::Schedule (Seconds (1.1), &TestUlOfdmaPpduUid::SendSuPpdu, this, 0);
1300 Simulator::Schedule (Seconds (1.1), &TestUlOfdmaPpduUid::CheckUid, this, 0, 1);
1301
1302 //Send HE TB PPDU from STAs to AP.
1303 //PPDU UID should NOT be incremented since HE TB PPDUs reuse the UID of the immediately
1304 //preceding correctly received PPDU (which normally contains the trigger frame).
1305 Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::SendTbPpdu, this);
1306 Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::CheckUid, this, 1, 1);
1307 Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::CheckUid, this, 2, 1);
1308
1309 //Send HE SU PPDU from STA1.
1310 //PPDU UID should be incremented since this is a new PPDU.
1311 Simulator::Schedule (Seconds (1.2), &TestUlOfdmaPpduUid::SendSuPpdu, this, 1);
1312 Simulator::Schedule (Seconds (1.2), &TestUlOfdmaPpduUid::CheckUid, this, 1, 2);
1313
1314 Simulator::Run ();
1315 Simulator::Destroy ();
1316 }
1317
1318 /**
1319 * \ingroup wifi-test
1320 * \ingroup tests
1321 *
1322 * \brief UL-OFDMA multiple RX events test
1323 */
1324 class TestMultipleHeTbPreambles : public TestCase
1325 {
1326 public:
1327 TestMultipleHeTbPreambles ();
1328 virtual ~TestMultipleHeTbPreambles ();
1329
1330 private:
1331 void DoSetup (void) override;
1332 void DoTeardown (void) override;
1333 void DoRun (void) override;
1334
1335 /**
1336 * Receive HE TB PPDU function.
1337 *
1338 * \param uid the UID used to identify a set of HE TB PPDUs belonging to the same UL-MU transmission
1339 * \param staId the STA ID
1340 * \param txPowerWatts the TX power in watts
1341 * \param payloadSize the size of the payload in bytes
1342 */
1343 void RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize);
1344
1345 /**
1346 * Receive OFDMA part of HE TB PPDU function.
1347 * Immediately schedules DoRxHeTbPpduOfdmaPart.
1348 *
1349 * \param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
1350 */
1351 void RxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma);
1352 /**
1353 * Receive OFDMA part of HE TB PPDU function.
1354 * Actual reception call.
1355 *
1356 * \param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
1357 */
1358 void DoRxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma);
1359
1360 /**
1361 * RX dropped function
1362 * \param p the packet
1363 * \param reason the reason
1364 */
1365 void RxDropped (Ptr<const Packet> p, WifiPhyRxfailureReason reason);
1366
1367 /**
1368 * Reset function
1369 */
1370 void Reset (void);
1371
1372 /**
1373 * Check the received HE TB preambles
1374 * \param nEvents the number of events created by the PHY
1375 * \param uids the vector of expected UIDs
1376 */
1377 void CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids);
1378
1379 /**
1380 * Check the number of bytes dropped
1381 * \param expectedBytesDropped the expected number of bytes dropped
1382 */
1383 void CheckBytesDropped (size_t expectedBytesDropped);
1384
1385 Ptr<OfdmaSpectrumWifiPhy> m_phy; ///< Phy
1386
1387 uint64_t m_totalBytesDropped; ///< total number of dropped bytes
1388 };
1389
TestMultipleHeTbPreambles()1390 TestMultipleHeTbPreambles::TestMultipleHeTbPreambles ()
1391 : TestCase ("UL-OFDMA multiple RX events test"),
1392 m_totalBytesDropped (0)
1393 {
1394 }
1395
~TestMultipleHeTbPreambles()1396 TestMultipleHeTbPreambles::~TestMultipleHeTbPreambles ()
1397 {
1398 }
1399
1400 void
Reset(void)1401 TestMultipleHeTbPreambles::Reset (void)
1402 {
1403 NS_LOG_FUNCTION (this);
1404 m_totalBytesDropped = 0;
1405 //We have to reset PHY here since we do not trigger OFDMA payload RX event in this test
1406 m_phy->Reset ();
1407 }
1408
1409 void
RxDropped(Ptr<const Packet> p,WifiPhyRxfailureReason reason)1410 TestMultipleHeTbPreambles::RxDropped (Ptr<const Packet> p, WifiPhyRxfailureReason reason)
1411 {
1412 NS_LOG_FUNCTION (this << p << reason);
1413 m_totalBytesDropped += (p->GetSize () - 30);
1414 }
1415
1416 void
CheckHeTbPreambles(size_t nEvents,std::vector<uint64_t> uids)1417 TestMultipleHeTbPreambles::CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids)
1418 {
1419 auto events = m_phy->GetCurrentPreambleEvents ();
1420 NS_TEST_ASSERT_MSG_EQ (events.size (), nEvents, "The number of UL MU events is not correct!");
1421 for (auto const& uid : uids)
1422 {
1423 auto pair = std::make_pair (uid, WIFI_PREAMBLE_HE_TB);
1424 auto it = events.find (pair);
1425 bool found = (it != events.end ());
1426 NS_TEST_ASSERT_MSG_EQ (found, true, "HE TB PPDU with UID " << uid << " has not been received!");
1427 }
1428 }
1429
1430 void
CheckBytesDropped(size_t expectedBytesDropped)1431 TestMultipleHeTbPreambles::CheckBytesDropped (size_t expectedBytesDropped)
1432 {
1433 NS_TEST_ASSERT_MSG_EQ (m_totalBytesDropped, expectedBytesDropped, "The number of dropped bytes is not correct!");
1434 }
1435
1436 void
RxHeTbPpdu(uint64_t uid,uint16_t staId,double txPowerWatts,size_t payloadSize)1437 TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize)
1438 {
1439 WifiConstPsduMap psdus;
1440 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1441
1442 HeRu::RuSpec ru (HeRu::RU_106_TONE, staId, false);
1443 ru.SetPhyIndex (DEFAULT_CHANNEL_WIDTH, 0);
1444 txVector.SetRu (ru, staId);
1445 txVector.SetMode (HePhy::GetHeMcs7 (), staId);
1446 txVector.SetNss (1, staId);
1447
1448 Ptr<Packet> pkt = Create<Packet> (payloadSize);
1449 WifiMacHeader hdr;
1450 hdr.SetType (WIFI_MAC_QOSDATA);
1451 hdr.SetQosTid (0);
1452 hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1453 hdr.SetSequenceNumber (1);
1454 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1455 psdus.insert (std::make_pair (staId, psdu));
1456
1457 Time ppduDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand (), staId);
1458 Ptr<HePpdu> ppdu = Create<HePpdu> (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid,
1459 HePpdu::PSD_HE_TB_NON_OFDMA_PORTION);
1460
1461 //Send non-OFDMA part
1462 Time nonOfdmaDuration = m_phy->GetHePhy ()->CalculateNonOfdmaDurationForHeTb (txVector);
1463 uint32_t centerFrequency = m_phy->GetHePhy ()->GetCenterFrequencyForNonOfdmaPart (txVector, staId);
1464 uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1465 uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
1466 Ptr<SpectrumValue> rxPsd = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerWatts, m_phy->GetGuardBandwidth (channelWidth));
1467 Ptr<WifiSpectrumSignalParameters> rxParams = Create<WifiSpectrumSignalParameters> ();
1468 rxParams->psd = rxPsd;
1469 rxParams->txPhy = 0;
1470 rxParams->duration = nonOfdmaDuration;
1471 rxParams->ppdu = ppdu;
1472
1473 m_phy->StartRx (rxParams);
1474
1475 //Schedule OFDMA part
1476 Ptr<HePpdu> ppduOfdma = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
1477 ppduOfdma->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
1478 WifiSpectrumBand band = m_phy->GetHePhy ()->GetRuBandForRx (txVector, staId);
1479 Ptr<SpectrumValue> rxPsdOfdma = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH, band);
1480 Ptr<WifiSpectrumSignalParameters> rxParamsOfdma = Create<WifiSpectrumSignalParameters> ();
1481 rxParamsOfdma->psd = rxPsd;
1482 rxParamsOfdma->txPhy = 0;
1483 rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
1484 rxParamsOfdma->ppdu = ppduOfdma;
1485 Simulator::Schedule (nonOfdmaDuration, &TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1486 }
1487
1488 void
RxHeTbPpduOfdmaPart(Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)1489 TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)
1490 {
1491 Simulator::ScheduleNow (&TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1492 }
1493
1494 void
DoRxHeTbPpduOfdmaPart(Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)1495 TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)
1496 {
1497 //This is needed to make sure the OFDMA part is started as the last event since HE-SIG-A should end at the exact same time as the start
1498 //For normal WifiNetDevices, this the reception of the OFDMA part is scheduled after end of HE-SIG-A decoding.
1499 m_phy->StartRx (rxParamsOfdma);
1500 }
1501
1502 void
DoSetup(void)1503 TestMultipleHeTbPreambles::DoSetup (void)
1504 {
1505 Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice> ();
1506 m_phy = CreateObject<OfdmaSpectrumWifiPhy> (0);
1507 m_phy->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1508 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1509 Ptr<ApWifiMac> mac = CreateObject<ApWifiMac> ();
1510 mac->SetAttribute ("BeaconGeneration", BooleanValue (false));
1511 dev->SetMac (mac);
1512 m_phy->SetErrorRateModel (error);
1513 m_phy->SetChannelNumber (DEFAULT_CHANNEL_NUMBER);
1514 m_phy->SetFrequency (DEFAULT_FREQUENCY);
1515 m_phy->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1516 m_phy->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&TestMultipleHeTbPreambles::RxDropped, this));
1517 m_phy->SetDevice (dev);
1518 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1519 preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
1520 preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
1521 m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1522 }
1523
1524 void
DoTeardown(void)1525 TestMultipleHeTbPreambles::DoTeardown (void)
1526 {
1527 m_phy->Dispose ();
1528 m_phy = 0;
1529 }
1530
1531 void
DoRun(void)1532 TestMultipleHeTbPreambles::DoRun (void)
1533 {
1534 RngSeedManager::SetSeed (1);
1535 RngSeedManager::SetRun (1);
1536 int64_t streamNumber = 0;
1537 m_phy->AssignStreams (streamNumber);
1538
1539 double txPowerWatts = 0.01;
1540
1541 {
1542 //Verify a single UL MU transmission with two stations belonging to the same BSS
1543 std::vector<uint64_t> uids {0};
1544 Simulator::Schedule (Seconds (1), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1545 Simulator::Schedule (Seconds (1) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1546 //Check that we received a single UL MU transmission with the corresponding UID
1547 Simulator::Schedule (Seconds (1.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, uids);
1548 Simulator::Schedule (Seconds (1.5), &TestMultipleHeTbPreambles::Reset, this);
1549 }
1550
1551 {
1552 //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1553 //arrives during the preamble detection window and with half the power of the first transmission.
1554 std::vector<uint64_t> uids {1, 2};
1555 Simulator::Schedule (Seconds (2), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1556 Simulator::Schedule (Seconds (2) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1557 Simulator::Schedule (Seconds (2) + NanoSeconds (200), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts / 2, 1003);
1558 Simulator::Schedule (Seconds (2) + NanoSeconds (300), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts / 2, 1004);
1559 //Check that we received the correct reception of 2 UL MU transmissions with the corresponding UIDs
1560 Simulator::Schedule (Seconds (2.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 2, uids);
1561 Simulator::Schedule (Seconds (2.5), &TestMultipleHeTbPreambles::Reset, this);
1562 //TODO: verify PPDUs from second UL MU transmission are dropped
1563 }
1564
1565 {
1566 //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1567 //arrives during the preamble detection window and with twice the power of the first transmission.
1568 std::vector<uint64_t> uids {3, 4};
1569 Simulator::Schedule (Seconds (3), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts / 2, 1001);
1570 Simulator::Schedule (Seconds (3) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts / 2, 1002);
1571 Simulator::Schedule (Seconds (3) + NanoSeconds (200), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1572 Simulator::Schedule (Seconds (3) + NanoSeconds (300), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1573 //Check that we received the correct reception of 2 UL MU transmissions with the corresponding UIDs
1574 Simulator::Schedule (Seconds (3.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 2, uids);
1575 Simulator::Schedule (Seconds (3.5), &TestMultipleHeTbPreambles::Reset, this);
1576 //TODO: verify PPDUs from first UL MU transmission are dropped
1577 }
1578
1579 {
1580 //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1581 //arrives during PHY header reception and with the same power as the first transmission.
1582 std::vector<uint64_t> uids {5, 6};
1583 Simulator::Schedule (Seconds (4), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1584 Simulator::Schedule (Seconds (4) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1585 Simulator::Schedule (Seconds (4) + MicroSeconds (5), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1586 Simulator::Schedule (Seconds (4) + MicroSeconds (5) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1587 //Check that we received the correct reception of the first UL MU transmission with the corresponding UID (second one dropped)
1588 Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, std::vector<uint64_t> {uids[0]});
1589 //The packets of the second UL MU transmission should have been dropped
1590 Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1003 + 1004);
1591 Simulator::Schedule (Seconds (4.5), &TestMultipleHeTbPreambles::Reset, this);
1592 }
1593
1594 {
1595 //Verify the correct reception of one UL MU transmission out of 2 with two stations per BSS, where the second transmission
1596 //arrives during payload reception and with the same power as the first transmission.
1597 std::vector<uint64_t> uids {7, 8};
1598 Simulator::Schedule (Seconds (5), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1599 Simulator::Schedule (Seconds (5) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1600 Simulator::Schedule (Seconds (5) + MicroSeconds (50), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1601 Simulator::Schedule (Seconds (5) + MicroSeconds (50) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1602 //Check that we received the correct reception of the first UL MU transmission with the corresponding UID (second one dropped)
1603 Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, std::vector<uint64_t> {uids[0]});
1604 //The packets of the second UL MU transmission should have been dropped
1605 Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1003 + 1004);
1606 Simulator::Schedule (Seconds (5.5), &TestMultipleHeTbPreambles::Reset, this);
1607 }
1608
1609 {
1610 //Verify the correct reception of a single UL MU transmission with two stations belonging to the same BSS,
1611 //and the second PPDU arrives 500ns after the first PPDU, i.e. it exceeds the delay spread of 400ns
1612 std::vector<uint64_t> uids {9};
1613 Simulator::Schedule (Seconds (6), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1614 Simulator::Schedule (Seconds (6) + NanoSeconds (500), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1615 //Check that we received a single UL MU transmission with the corresponding UID
1616 Simulator::Schedule (Seconds (6.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, uids);
1617 //The first packet of 1001 bytes should be dropped because preamble is not detected after 4us (because the PPDU that arrived at 500ns is interfering):
1618 //the second HE TB PPDU is acting as interference since it arrived after the maximum allowed 400ns.
1619 //Obviously, that second packet of 1002 bytes is dropped as well.
1620 Simulator::Schedule (Seconds (6.0) + MicroSeconds (5), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1001 + 1002);
1621 Simulator::Schedule (Seconds (6.5), &TestMultipleHeTbPreambles::Reset, this);
1622 }
1623
1624 Simulator::Run ();
1625 Simulator::Destroy ();
1626 }
1627
1628 /**
1629 * \ingroup wifi-test
1630 * \ingroup tests
1631 *
1632 * \brief UL-OFDMA PHY test
1633 */
1634 class TestUlOfdmaPhyTransmission : public TestCase
1635 {
1636 public:
1637 TestUlOfdmaPhyTransmission ();
1638 virtual ~TestUlOfdmaPhyTransmission ();
1639
1640 private:
1641 void DoSetup (void) override;
1642 void DoTeardown (void) override;
1643 void DoRun (void) override;
1644
1645 /**
1646 * Get TXVECTOR for HE TB PPDU.
1647 * \param txStaId the ID of the TX STA
1648 * \param index the RU index used for the transmission
1649 * \param bssColor the BSS color of the TX STA
1650 * \return the TXVECTOR for HE TB PPDU
1651 */
1652 WifiTxVector GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const;
1653 /**
1654 * Send HE TB PPDU function
1655 * \param txStaId the ID of the TX STA
1656 * \param index the RU index used for the transmission
1657 * \param payloadSize the size of the payload in bytes
1658 * \param uid the UID of the trigger frame that is initiating this transmission
1659 * \param bssColor the BSS color of the TX STA
1660 */
1661 void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1662
1663 /**
1664 * Send HE SU PPDU function
1665 * \param txStaId the ID of the TX STA
1666 * \param payloadSize the size of the payload in bytes
1667 * \param uid the UID of the trigger frame that is initiating this transmission
1668 * \param bssColor the BSS color of the TX STA
1669 */
1670 void SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1671
1672 /**
1673 * Set the BSS color
1674 * \param phy the PHY
1675 * \param bssColor the BSS color
1676 */
1677 void SetBssColor (Ptr<WifiPhy> phy, uint8_t bssColor);
1678
1679 /**
1680 * Set the PSD limit
1681 * \param phy the PHY
1682 * \param psdLimit the PSD limit in dBm/MHz
1683 */
1684 void SetPsdLimit (Ptr<WifiPhy> phy, double psdLimit);
1685
1686 /**
1687 * Generate interference function
1688 * \param interferencePsd the PSD of the interference to be generated
1689 * \param duration the duration of the interference
1690 */
1691 void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
1692 /**
1693 * Stop interference function
1694 */
1695 void StopInterference (void);
1696
1697 /**
1698 * Run one function
1699 */
1700 void RunOne ();
1701
1702 /**
1703 * Check the received PSDUs from STA1
1704 * \param expectedSuccess the expected number of success
1705 * \param expectedFailures the expected number of failures
1706 * \param expectedBytes the expected number of bytes
1707 */
1708 void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1709
1710 /**
1711 * Check the received PSDUs from STA2
1712 * \param expectedSuccess the expected number of success
1713 * \param expectedFailures the expected number of failures
1714 * \param expectedBytes the expected number of bytes
1715 */
1716 void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1717
1718 /**
1719 * Check the received power for the non-OFDMA of the HE TB PPDUs over the given band
1720 * \param phy the PHY
1721 * \param band the WifiSpectrumBand over which the power is measured
1722 * \param expectedRxPower the expected received power in W
1723 */
1724 void CheckNonOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1725 /**
1726 * Check the received power for the OFDMA part of the HE TB PPDUs over the given band
1727 * \param phy the PHY
1728 * \param band the WifiSpectrumBand over which the power is measured
1729 * \param expectedRxPower the expected received power in W
1730 */
1731 void CheckOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1732
1733 /**
1734 * Verify all events are cleared at end of TX or RX
1735 */
1736 void VerifyEventsCleared (void);
1737
1738 /**
1739 * Check the PHY state
1740 * \param phy the PHY
1741 * \param expectedState the expected state of the PHY
1742 */
1743 void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
1744 /// \copydoc CheckPhyState
1745 void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
1746
1747 /**
1748 * Reset function
1749 */
1750 void Reset ();
1751
1752 /**
1753 * Receive success function
1754 * \param psdu the PSDU
1755 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1756 * \param txVector the transmit vector
1757 * \param statusPerMpdu reception status per MPDU
1758 */
1759 void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1760
1761 /**
1762 * Receive failure function
1763 * \param psdu the PSDU
1764 */
1765 void RxFailure (Ptr<WifiPsdu> psdu);
1766
1767 /**
1768 * Schedule test to perform.
1769 * The interference generation should be scheduled apart.
1770 *
1771 * \param delay the reference delay to schedule the events
1772 * \param solicited flag indicating if HE TB PPDUs were solicited by the AP
1773 * \param expectedStateAtEnd the expected state of the PHY at the end of the reception
1774 * \param expectedSuccessFromSta1 the expected number of success from STA 1
1775 * \param expectedFailuresFromSta1 the expected number of failures from STA 1
1776 * \param expectedBytesFromSta1 the expected number of bytes from STA 1
1777 * \param expectedSuccessFromSta2 the expected number of success from STA 2
1778 * \param expectedFailuresFromSta2 the expected number of failures from STA 2
1779 * \param expectedBytesFromSta2 the expected number of bytes from STA 2
1780 * \param scheduleTxSta1 flag indicating to schedule a HE TB PPDU from STA 1
1781 * \param expectedStateBeforeEnd the expected state of the PHY before the end of the transmission
1782 */
1783 void ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
1784 uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
1785 uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
1786 bool scheduleTxSta1 = true, WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX);
1787
1788 /**
1789 * Schedule power measurement related checks.
1790 *
1791 * \param delay the reference delay used to schedule the events
1792 * \param rxPowerNonOfdmaRu1 the received power (in watts) on the non-OFDMA part of RU1
1793 * \param rxPowerNonOfdmaRu2 the received power (in watts) on the non-OFDMA part of RU2
1794 * \param rxPowerOfdmaRu1 the received power (in watts) on RU1
1795 * \param rxPowerOfdmaRu2 the received power (in watts) on RU2
1796 */
1797 void SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
1798 double rxPowerOfdmaRu1, double rxPowerOfdmaRu2);
1799 /**
1800 * Log scenario description
1801 *
1802 * \param log the scenario description to add to log
1803 */
1804 void LogScenario (std::string log) const;
1805
1806 Ptr<OfdmaSpectrumWifiPhy> m_phyAp; ///< PHY of AP
1807 Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
1808 Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
1809 Ptr<OfdmaSpectrumWifiPhy> m_phySta3; ///< PHY of STA 3
1810
1811 Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
1812
1813 uint32_t m_countRxSuccessFromSta1; ///< count RX success from STA 1
1814 uint32_t m_countRxSuccessFromSta2; ///< count RX success from STA 2
1815 uint32_t m_countRxFailureFromSta1; ///< count RX failure from STA 1
1816 uint32_t m_countRxFailureFromSta2; ///< count RX failure from STA 2
1817 uint32_t m_countRxBytesFromSta1; ///< count RX bytes from STA 1
1818 uint32_t m_countRxBytesFromSta2; ///< count RX bytes from STA 2
1819
1820 uint16_t m_frequency; ///< frequency in MHz
1821 uint16_t m_channelWidth; ///< channel width in MHz
1822 Time m_expectedPpduDuration; ///< expected duration to send MU PPDU
1823 };
1824
TestUlOfdmaPhyTransmission()1825 TestUlOfdmaPhyTransmission::TestUlOfdmaPhyTransmission ()
1826 : TestCase ("UL-OFDMA PHY test"),
1827 m_countRxSuccessFromSta1 (0),
1828 m_countRxSuccessFromSta2 (0),
1829 m_countRxFailureFromSta1 (0),
1830 m_countRxFailureFromSta2 (0),
1831 m_countRxBytesFromSta1 (0),
1832 m_countRxBytesFromSta2 (0),
1833 m_frequency (DEFAULT_FREQUENCY),
1834 m_channelWidth (DEFAULT_CHANNEL_WIDTH),
1835 m_expectedPpduDuration (NanoSeconds (271200))
1836 {
1837 }
1838
1839 void
SendHeSuPpdu(uint16_t txStaId,std::size_t payloadSize,uint64_t uid,uint8_t bssColor)1840 TestUlOfdmaPhyTransmission::SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
1841 {
1842 NS_LOG_FUNCTION (this << txStaId << payloadSize << uid << +bssColor);
1843 WifiConstPsduMap psdus;
1844
1845 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, m_channelWidth, false, false, false, bssColor);
1846
1847 Ptr<Packet> pkt = Create<Packet> (payloadSize);
1848 WifiMacHeader hdr;
1849 hdr.SetType (WIFI_MAC_QOSDATA);
1850 hdr.SetQosTid (0);
1851 hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1852 std::ostringstream addr;
1853 addr << "00:00:00:00:00:0" << txStaId;
1854 hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
1855 hdr.SetSequenceNumber (1);
1856 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1857 psdus.insert (std::make_pair (SU_STA_ID, psdu));
1858
1859 Ptr<OfdmaSpectrumWifiPhy> phy;
1860 if (txStaId == 1)
1861 {
1862 phy = m_phySta1;
1863 }
1864 else if (txStaId == 2)
1865 {
1866 phy = m_phySta2;
1867 }
1868 else if (txStaId == 3)
1869 {
1870 phy = m_phySta3;
1871 }
1872 else if (txStaId == 0)
1873 {
1874 phy = m_phyAp;
1875 }
1876 phy->SetPpduUid (uid);
1877 phy->Send (psdus, txVector);
1878 }
1879
1880 WifiTxVector
GetTxVectorForHeTbPpdu(uint16_t txStaId,std::size_t index,uint8_t bssColor) const1881 TestUlOfdmaPhyTransmission::GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const
1882 {
1883 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, m_channelWidth, false, false, false, bssColor);
1884
1885 HeRu::RuType ruType = HeRu::RU_106_TONE;
1886 if (m_channelWidth == 20)
1887 {
1888 ruType = HeRu::RU_106_TONE;
1889 }
1890 else if (m_channelWidth == 40)
1891 {
1892 ruType = HeRu::RU_242_TONE;
1893 }
1894 else if (m_channelWidth == 80)
1895 {
1896 ruType = HeRu::RU_484_TONE;
1897 }
1898 else if (m_channelWidth == 160)
1899 {
1900 ruType = HeRu::RU_996_TONE;
1901 }
1902 else
1903 {
1904 NS_ASSERT_MSG (false, "Unsupported channel width");
1905 }
1906
1907 bool primary80MHz = true;
1908 if (m_channelWidth == 160 && index == 2)
1909 {
1910 primary80MHz = false;
1911 index = 1;
1912 }
1913 HeRu::RuSpec ru (ruType, index, primary80MHz);
1914 ru.SetPhyIndex (m_channelWidth, 0);
1915 txVector.SetRu (ru, txStaId);
1916 txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
1917 txVector.SetNss (1, txStaId);
1918 return txVector;
1919 }
1920
1921 void
SendHeTbPpdu(uint16_t txStaId,std::size_t index,std::size_t payloadSize,uint64_t uid,uint8_t bssColor)1922 TestUlOfdmaPhyTransmission::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
1923 {
1924 NS_LOG_FUNCTION (this << txStaId << index << payloadSize << uid << +bssColor);
1925 WifiConstPsduMap psdus;
1926
1927 WifiTxVector txVector = GetTxVectorForHeTbPpdu (txStaId, index, bssColor);
1928 Ptr<Packet> pkt = Create<Packet> (payloadSize);
1929 WifiMacHeader hdr;
1930 hdr.SetType (WIFI_MAC_QOSDATA);
1931 hdr.SetQosTid (0);
1932 hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1933 std::ostringstream addr;
1934 addr << "00:00:00:00:00:0" << txStaId;
1935 hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
1936 hdr.SetSequenceNumber (1);
1937 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1938 psdus.insert (std::make_pair (txStaId, psdu));
1939
1940 Ptr<OfdmaSpectrumWifiPhy> phy;
1941 if (txStaId == 1)
1942 {
1943 phy = m_phySta1;
1944 }
1945 else if (txStaId == 2)
1946 {
1947 phy = m_phySta2;
1948 }
1949 else if (txStaId == 3)
1950 {
1951 phy = m_phySta3;
1952 }
1953
1954 Time txDuration = phy->CalculateTxDuration (psdu->GetSize (), txVector, phy->GetPhyBand (), txStaId);
1955 txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
1956
1957 phy->SetPpduUid (uid);
1958 phy->Send (psdus, txVector);
1959 }
1960
1961 void
GenerateInterference(Ptr<SpectrumValue> interferencePsd,Time duration)1962 TestUlOfdmaPhyTransmission::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
1963 {
1964 NS_LOG_FUNCTION (this << duration);
1965 m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
1966 m_phyInterferer->SetPeriod (duration);
1967 m_phyInterferer->Start ();
1968 Simulator::Schedule (duration, &TestUlOfdmaPhyTransmission::StopInterference, this);
1969 }
1970
1971 void
StopInterference(void)1972 TestUlOfdmaPhyTransmission::StopInterference (void)
1973 {
1974 m_phyInterferer->Stop();
1975 }
1976
~TestUlOfdmaPhyTransmission()1977 TestUlOfdmaPhyTransmission::~TestUlOfdmaPhyTransmission ()
1978 {
1979 }
1980
1981 void
RxSuccess(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)1982 TestUlOfdmaPhyTransmission::RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
1983 {
1984 NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << rxSignalInfo << txVector);
1985 if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
1986 {
1987 m_countRxSuccessFromSta1++;
1988 m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
1989 }
1990 else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
1991 {
1992 m_countRxSuccessFromSta2++;
1993 m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
1994 }
1995 }
1996
1997 void
RxFailure(Ptr<WifiPsdu> psdu)1998 TestUlOfdmaPhyTransmission::RxFailure (Ptr<WifiPsdu> psdu)
1999 {
2000 NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2001 if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2002 {
2003 m_countRxFailureFromSta1++;
2004 }
2005 else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2006 {
2007 m_countRxFailureFromSta2++;
2008 }
2009 }
2010
2011 void
CheckRxFromSta1(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2012 TestUlOfdmaPhyTransmission::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2013 {
2014 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
2015 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
2016 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
2017 }
2018
2019 void
CheckRxFromSta2(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2020 TestUlOfdmaPhyTransmission::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2021 {
2022 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
2023 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
2024 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
2025 }
2026
2027 void
CheckNonOfdmaRxPower(Ptr<OfdmaSpectrumWifiPhy> phy,WifiSpectrumBand band,double expectedRxPower)2028 TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower)
2029 {
2030 Ptr<Event> event = phy->GetCurrentEvent ();
2031 NS_ASSERT (event);
2032 double rxPower = event->GetRxPowerW (band);
2033 NS_LOG_FUNCTION (this << band.first << band.second << expectedRxPower << rxPower);
2034 //Since there is out of band emission due to spectrum mask, the tolerance cannot be very low
2035 NS_TEST_ASSERT_MSG_EQ_TOL (rxPower, expectedRxPower, 5e-3, "RX power " << rxPower << " over (" << band.first << ", " << band.second << ") does not match expected power " << expectedRxPower << " at " << Simulator::Now ());
2036 }
2037
2038 void
CheckOfdmaRxPower(Ptr<OfdmaSpectrumWifiPhy> phy,WifiSpectrumBand band,double expectedRxPower)2039 TestUlOfdmaPhyTransmission::CheckOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower)
2040 {
2041 /**
2042 * The current event cannot be used since it points to the preamble part of the HE TB PPDU.
2043 * We will have to check if the expected power is indeed the max power returning a positive
2044 * duration when calling GetEnergyDuration.
2045 */
2046 NS_LOG_FUNCTION (this << band.first << band.second << expectedRxPower);
2047 double step = 5e-3;
2048 if (expectedRxPower > 0.0)
2049 {
2050 NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower - step, band).IsStrictlyPositive (), true,
2051 "At least " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2052 NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower + step, band).IsStrictlyPositive (), false,
2053 "At most " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2054 }
2055 else
2056 {
2057 NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower + step, band).IsStrictlyPositive (), false,
2058 "At most " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2059 }
2060 }
2061
2062 void
VerifyEventsCleared(void)2063 TestUlOfdmaPhyTransmission::VerifyEventsCleared (void)
2064 {
2065 NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
2066 NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
2067 NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
2068 }
2069
2070 void
CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)2071 TestUlOfdmaPhyTransmission::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
2072 {
2073 //This is needed to make sure PHY state will be checked as the last event if a state change occurred at the exact same time as the check
2074 Simulator::ScheduleNow (&TestUlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
2075 }
2076
2077 void
DoCheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)2078 TestUlOfdmaPhyTransmission::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
2079 {
2080 WifiPhyState currentState;
2081 PointerValue ptr;
2082 phy->GetAttribute ("State", ptr);
2083 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
2084 currentState = state->GetState ();
2085 NS_LOG_FUNCTION (this << currentState);
2086 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
2087 }
2088
2089 void
Reset(void)2090 TestUlOfdmaPhyTransmission::Reset (void)
2091 {
2092 m_countRxSuccessFromSta1 = 0;
2093 m_countRxSuccessFromSta2 = 0;
2094 m_countRxFailureFromSta1 = 0;
2095 m_countRxFailureFromSta2 = 0;
2096 m_countRxBytesFromSta1 = 0;
2097 m_countRxBytesFromSta2 = 0;
2098 m_phySta1->SetPpduUid (0);
2099 m_phySta1->SetTriggerFrameUid (0);
2100 m_phySta2->SetTriggerFrameUid (0);
2101 SetBssColor (m_phyAp, 0);
2102 }
2103
2104 void
SetBssColor(Ptr<WifiPhy> phy,uint8_t bssColor)2105 TestUlOfdmaPhyTransmission::SetBssColor (Ptr<WifiPhy> phy, uint8_t bssColor)
2106 {
2107 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (phy->GetDevice ());
2108 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
2109 heConfiguration->SetAttribute ("BssColor", UintegerValue (bssColor));
2110 }
2111
2112 void
SetPsdLimit(Ptr<WifiPhy> phy,double psdLimit)2113 TestUlOfdmaPhyTransmission::SetPsdLimit (Ptr<WifiPhy> phy, double psdLimit)
2114 {
2115 NS_LOG_FUNCTION (this << phy << psdLimit);
2116 phy->SetAttribute ("PowerDensityLimit", DoubleValue (psdLimit));
2117 }
2118
2119 void
DoSetup(void)2120 TestUlOfdmaPhyTransmission::DoSetup (void)
2121 {
2122 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
2123 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
2124 lossModel->SetFrequency (m_frequency);
2125 spectrumChannel->AddPropagationLossModel (lossModel);
2126 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
2127 spectrumChannel->SetPropagationDelayModel (delayModel);
2128
2129 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
2130 preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-8)); //to ensure that transmission in neighboring channel is ignored (16 dBm baseline)
2131 preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (-100)); //no limit on SNR
2132
2133 Ptr<Node> apNode = CreateObject<Node> ();
2134 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
2135 Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
2136 apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
2137 apDev->SetMac (apMac);
2138 m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
2139 m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
2140 m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2141 Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
2142 apDev->SetHeConfiguration (heConfiguration);
2143 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
2144 m_phyAp->SetErrorRateModel (error);
2145 m_phyAp->SetDevice (apDev);
2146 m_phyAp->SetChannel (spectrumChannel);
2147 m_phyAp->SetReceiveOkCallback (MakeCallback (&TestUlOfdmaPhyTransmission::RxSuccess, this));
2148 m_phyAp->SetReceiveErrorCallback (MakeCallback (&TestUlOfdmaPhyTransmission::RxFailure, this));
2149 m_phyAp->SetPreambleDetectionModel (preambleDetectionModel);
2150 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
2151 m_phyAp->SetMobility (apMobility);
2152 apDev->SetPhy (m_phyAp);
2153 apNode->AggregateObject (apMobility);
2154 apNode->AddDevice (apDev);
2155
2156 Ptr<Node> sta1Node = CreateObject<Node> ();
2157 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
2158 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
2159 m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
2160 m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2161 m_phySta1->SetErrorRateModel (error);
2162 m_phySta1->SetDevice (sta1Dev);
2163 m_phySta1->SetChannel (spectrumChannel);
2164 m_phySta1->SetPreambleDetectionModel (preambleDetectionModel);
2165 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
2166 m_phySta1->SetMobility (sta1Mobility);
2167 sta1Dev->SetPhy (m_phySta1);
2168 sta1Node->AggregateObject (sta1Mobility);
2169 sta1Node->AddDevice (sta1Dev);
2170
2171 Ptr<Node> sta2Node = CreateObject<Node> ();
2172 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
2173 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
2174 m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
2175 m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2176 m_phySta2->SetErrorRateModel (error);
2177 m_phySta2->SetDevice (sta2Dev);
2178 m_phySta2->SetChannel (spectrumChannel);
2179 m_phySta2->SetPreambleDetectionModel (preambleDetectionModel);
2180 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
2181 m_phySta2->SetMobility (sta2Mobility);
2182 sta2Dev->SetPhy (m_phySta2);
2183 sta2Node->AggregateObject (sta2Mobility);
2184 sta2Node->AddDevice (sta2Dev);
2185
2186 Ptr<Node> sta3Node = CreateObject<Node> ();
2187 Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
2188 m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
2189 m_phySta3->CreateWifiSpectrumPhyInterface (sta3Dev);
2190 m_phySta3->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2191 m_phySta3->SetErrorRateModel (error);
2192 m_phySta3->SetDevice (sta3Dev);
2193 m_phySta3->SetChannel (spectrumChannel);
2194 m_phySta3->SetPreambleDetectionModel (preambleDetectionModel);
2195 Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
2196 m_phySta3->SetMobility (sta3Mobility);
2197 sta3Dev->SetPhy (m_phySta3);
2198 sta3Node->AggregateObject (sta3Mobility);
2199 sta3Node->AddDevice (sta3Dev);
2200
2201 Ptr<Node> interfererNode = CreateObject<Node> ();
2202 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
2203 m_phyInterferer = CreateObject<WaveformGenerator> ();
2204 m_phyInterferer->SetDevice (interfererDev);
2205 m_phyInterferer->SetChannel (spectrumChannel);
2206 m_phyInterferer->SetDutyCycle (1);
2207 interfererNode->AddDevice (interfererDev);
2208
2209 //Configure power attributes of all wifi devices
2210 std::list<Ptr<WifiPhy>> phys {m_phyAp, m_phySta1, m_phySta2, m_phySta3};
2211 for (auto & phy : phys)
2212 {
2213 phy->SetAttribute ("TxGain", DoubleValue (1.0));
2214 phy->SetAttribute ("TxPowerStart", DoubleValue (16.0));
2215 phy->SetAttribute ("TxPowerEnd", DoubleValue (16.0));
2216 phy->SetAttribute ("PowerDensityLimit", DoubleValue (100.0)); //no impact by default
2217 phy->SetAttribute ("RxGain", DoubleValue (2.0));
2218 }
2219 }
2220
2221 void
DoTeardown(void)2222 TestUlOfdmaPhyTransmission::DoTeardown (void)
2223 {
2224 m_phyAp->Dispose ();
2225 m_phyAp = 0;
2226 m_phySta1->Dispose ();
2227 m_phySta1 = 0;
2228 m_phySta2->Dispose ();
2229 m_phySta2 = 0;
2230 m_phySta3->Dispose ();
2231 m_phySta3 = 0;
2232 m_phyInterferer->Dispose ();
2233 m_phyInterferer = 0;
2234 }
2235
2236 void
LogScenario(std::string log) const2237 TestUlOfdmaPhyTransmission::LogScenario (std::string log) const
2238 {
2239 NS_LOG_INFO (log);
2240 }
2241
2242 void
ScheduleTest(Time delay,bool solicited,WifiPhyState expectedStateAtEnd,uint32_t expectedSuccessFromSta1,uint32_t expectedFailuresFromSta1,uint32_t expectedBytesFromSta1,uint32_t expectedSuccessFromSta2,uint32_t expectedFailuresFromSta2,uint32_t expectedBytesFromSta2,bool scheduleTxSta1,WifiPhyState expectedStateBeforeEnd)2243 TestUlOfdmaPhyTransmission::ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
2244 uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
2245 uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
2246 bool scheduleTxSta1, WifiPhyState expectedStateBeforeEnd)
2247 {
2248 //AP send SU packet with UID = 0 (2) to mimic transmission of solicited (unsolicited) HE TB PPDUs
2249 Simulator::Schedule (delay - MilliSeconds (10), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 0, 50, solicited ? 0 : 2, 0);
2250 //STA1 and STA2 send MU UL PPDUs addressed to AP
2251 if (scheduleTxSta1)
2252 {
2253 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 1, 1, 1000, 0, 0);
2254 }
2255 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 2, 2, 1001, 0, 0);
2256
2257 //Verify it takes m_expectedPpduDuration to transmit the PPDUs
2258 Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateBeforeEnd);
2259 Simulator::Schedule (delay + m_expectedPpduDuration, &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateAtEnd);
2260 //TODO: add checks on TX stop for STAs
2261
2262 delay += MilliSeconds (100);
2263 //Check reception state from STA 1
2264 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta1, this,
2265 expectedSuccessFromSta1, expectedFailuresFromSta1, expectedBytesFromSta1);
2266 //Check reception state from STA 2
2267 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta2, this,
2268 expectedSuccessFromSta2, expectedFailuresFromSta2, expectedBytesFromSta2);
2269 //Verify events data have been cleared
2270 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::VerifyEventsCleared, this);
2271
2272 delay += MilliSeconds (100);
2273 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2274 }
2275
2276 void
SchedulePowerMeasurementChecks(Time delay,double rxPowerNonOfdmaRu1,double rxPowerNonOfdmaRu2,double rxPowerOfdmaRu1,double rxPowerOfdmaRu2)2277 TestUlOfdmaPhyTransmission::SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
2278 double rxPowerOfdmaRu1, double rxPowerOfdmaRu2)
2279 {
2280 Time detectionDuration = WifiPhy::GetPreambleDetectionDuration ();
2281 WifiTxVector txVectorSta1 = GetTxVectorForHeTbPpdu (1, 1, 0);
2282 WifiTxVector txVectorSta2 = GetTxVectorForHeTbPpdu (2, 2, 0);
2283 Ptr<const HePhy> hePhy = m_phyAp->GetHePhy ();
2284 Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb (txVectorSta2);
2285 NS_ASSERT (nonOfdmaDuration == hePhy->CalculateNonOfdmaDurationForHeTb (txVectorSta1));
2286
2287 std::vector<double> rxPowerNonOfdma { rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2 };
2288 std::vector<WifiSpectrumBand> nonOfdmaBand { hePhy->GetNonOfdmaBand (txVectorSta1, 1), hePhy->GetNonOfdmaBand (txVectorSta2, 2) };
2289 std::vector<double> rxPowerOfdma { rxPowerOfdmaRu1, rxPowerOfdmaRu2 };
2290 std::vector<WifiSpectrumBand> ofdmaBand { hePhy->GetRuBandForRx (txVectorSta1, 1), hePhy->GetRuBandForRx (txVectorSta2, 2) };
2291
2292 for (uint8_t i = 0; i < 2; ++i)
2293 {
2294 /**
2295 * Perform checks at AP
2296 */
2297 //Check received power on non-OFDMA portion
2298 Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2299 &TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower, this, m_phyAp,
2300 nonOfdmaBand[i], rxPowerNonOfdma[i]);
2301 Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2302 &TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower, this, m_phyAp,
2303 nonOfdmaBand[i], rxPowerNonOfdma[i]);
2304 //Check received power on OFDMA portion
2305 Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2306 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phyAp,
2307 ofdmaBand[i], rxPowerOfdma[i]);
2308 Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2309 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phyAp,
2310 ofdmaBand[i], rxPowerOfdma[i]);
2311
2312 /**
2313 * Perform checks for non-transmitting STA (STA 3).
2314 * Cannot use CheckNonOfdmaRxPower method since current event may be reset if
2315 * preamble not detected (e.g. not on primary).
2316 */
2317 //Check received power on non-OFDMA portion
2318 Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2319 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2320 nonOfdmaBand[i], rxPowerNonOfdma[i]);
2321 Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2322 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2323 nonOfdmaBand[i], rxPowerNonOfdma[i]);
2324 //Check received power on OFDMA portion
2325 Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2326 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2327 ofdmaBand[i], rxPowerOfdma[i]);
2328 Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2329 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2330 ofdmaBand[i], rxPowerOfdma[i]);
2331 }
2332
2333 if (rxPowerOfdmaRu1 != 0.0)
2334 {
2335 /**
2336 * Perform checks for transmitting STA (STA 2) to ensure it has correctly logged
2337 * power received from other transmitting STA (STA 1).
2338 * Cannot use CheckNonOfdmaRxPower method since current event not set.
2339 */
2340 double rxPowerNonOfdmaSta1Only = (m_channelWidth >= 40) ? rxPowerNonOfdma[0] : rxPowerNonOfdma[0] / 2; //both STAs transmit over the same 20 MHz channel
2341 //Check received power on non-OFDMA portion
2342 Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2343 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2344 nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2345 Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2346 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2347 nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2348 //Check received power on OFDMA portion
2349 Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2350 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2351 ofdmaBand[0], rxPowerOfdma[0]);
2352 Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2353 &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2354 ofdmaBand[0], rxPowerOfdma[0]);
2355 }
2356 }
2357
2358 void
RunOne(void)2359 TestUlOfdmaPhyTransmission::RunOne (void)
2360 {
2361 RngSeedManager::SetSeed (1);
2362 RngSeedManager::SetRun (1);
2363 int64_t streamNumber = 0;
2364 m_phyAp->AssignStreams (streamNumber);
2365 m_phySta1->AssignStreams (streamNumber);
2366 m_phySta2->AssignStreams (streamNumber);
2367 m_phySta3->AssignStreams (streamNumber);
2368
2369 m_phyAp->SetFrequency (m_frequency);
2370 m_phyAp->SetChannelWidth (m_channelWidth);
2371
2372 m_phySta1->SetFrequency (m_frequency);
2373 m_phySta1->SetChannelWidth (m_channelWidth);
2374
2375 m_phySta2->SetFrequency (m_frequency);
2376 m_phySta2->SetChannelWidth (m_channelWidth);
2377
2378 m_phySta3->SetFrequency (m_frequency);
2379 m_phySta3->SetChannelWidth (m_channelWidth);
2380
2381 Time delay = Seconds (0.0);
2382 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2383 delay += Seconds (1.0);
2384
2385 /**
2386 * In all the following tests, 2 HE TB PPDUs of the same UL MU transmission
2387 * are sent on RU 1 for STA 1 and RU 2 for STA 2.
2388 * The difference between solicited and unsolicited lies in that their PPDU
2389 * ID correspond to the one of the immediately preceding HE SU PPDU (thus
2390 * mimicing trigger frame reception).
2391 */
2392
2393 //---------------------------------------------------------------------------
2394 //Verify that both solicited HE TB PPDUs have been corrected received
2395 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2396 "Reception of solicited HE TB PPDUs");
2397 ScheduleTest (delay, true,
2398 WifiPhyState::IDLE,
2399 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2400 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2401 delay += Seconds (1.0);
2402
2403 //---------------------------------------------------------------------------
2404 //Verify that both unsolicited HE TB PPDUs have been corrected received
2405 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2406 "Reception of unsolicited HE TB PPDUs");
2407 ScheduleTest (delay, false,
2408 WifiPhyState::IDLE,
2409 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2410 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2411 delay += Seconds (1.0);
2412
2413 //---------------------------------------------------------------------------
2414 //Generate an interference on RU 1 and verify that only STA 1's solicited HE TB PPDU has been impacted
2415 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2416 "Reception of solicited HE TB PPDUs with interference on RU 1 during PSDU reception");
2417 //A strong non-wifi interference is generated on RU 1 during PSDU reception
2418 BandInfo bandInfo;
2419 bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
2420 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
2421 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
2422 Bands bands;
2423 bands.push_back (bandInfo);
2424
2425 Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
2426 Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
2427 double interferencePower = 0.1; //watts
2428 *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
2429
2430 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
2431 ScheduleTest (delay, true,
2432 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2433 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2434 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2435 delay += Seconds (1.0);
2436
2437 //---------------------------------------------------------------------------
2438 //Generate an interference on RU 1 and verify that only STA 1's unsolicited HE TB PPDU has been impacted
2439 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2440 "Reception of unsolicited HE TB PPDUs with interference on RU 1 during PSDU reception");
2441 //A strong non-wifi interference is generated on RU 1 during PSDU reception
2442 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
2443 ScheduleTest (delay, false,
2444 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference (primary channel)
2445 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2446 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2447 delay += Seconds (1.0);
2448
2449 //---------------------------------------------------------------------------
2450 //Generate an interference on RU 2 and verify that only STA 2's solicited HE TB PPDU has been impacted
2451 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2452 "Reception of solicited HE TB PPDUs with interference on RU 2 during PSDU reception");
2453 //A strong non-wifi interference is generated on RU 2 during PSDU reception
2454 bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
2455 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
2456 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
2457 bands.clear ();
2458 bands.push_back (bandInfo);
2459
2460 Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
2461 Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
2462 *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
2463
2464 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
2465 ScheduleTest (delay, true,
2466 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY since measurement channel encompasses total channel width
2467 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2468 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2469 delay += Seconds (1.0);
2470
2471 //---------------------------------------------------------------------------
2472 //Generate an interference on RU 2 and verify that only STA 2's unsolicited HE TB PPDU has been impacted
2473 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2474 "Reception of unsolicited HE TB PPDUs with interference on RU 2 during PSDU reception");
2475 //A strong non-wifi interference is generated on RU 2 during PSDU reception
2476 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
2477 ScheduleTest (delay, false,
2478 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
2479 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2480 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2481 delay += Seconds (1.0);
2482
2483 //---------------------------------------------------------------------------
2484 //Generate an interference on the full band and verify that both solicited HE TB PPDUs have been impacted
2485 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2486 "Reception of solicited HE TB PPDUs with interference on the full band during PSDU reception");
2487 //A strong non-wifi interference is generated on the full band during PSDU reception
2488 bandInfo.fc = m_frequency * 1e6;
2489 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
2490 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
2491 bands.clear ();
2492 bands.push_back (bandInfo);
2493
2494 Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
2495 Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
2496 *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
2497
2498 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
2499 ScheduleTest (delay, true,
2500 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2501 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2502 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2503 delay += Seconds (1.0);
2504
2505 //---------------------------------------------------------------------------
2506 //Generate an interference on the full band and verify that both unsolicited HE TB PPDUs have been impacted
2507 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2508 "Reception of unsolicited HE TB PPDUs with interference on the full band during PSDU reception");
2509 //A strong non-wifi interference is generated on the full band during PSDU reception
2510 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
2511 ScheduleTest (delay, false,
2512 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2513 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2514 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2515 delay += Seconds (1.0);
2516
2517 //---------------------------------------------------------------------------
2518 //Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both solicited HE TB PPDUs have been impacted if they are on the same
2519 // 20 MHz channel. Only STA 1's solicited HE TB PPDU is impacted otherwise.
2520 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2521 "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
2522 //Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
2523 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
2524 //Expected figures from STA 2
2525 uint32_t succ, fail, bytes;
2526 if (m_channelWidth > 20)
2527 {
2528 //One PSDU of 1001 bytes should have been successfully received from STA 2 (since interference from STA 3 on distinct 20 MHz channel)
2529 succ = 1;
2530 fail = 0;
2531 bytes = 1001;
2532 }
2533 else
2534 {
2535 //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2536 succ = 0;
2537 fail = 1;
2538 bytes = 0;
2539 }
2540 ScheduleTest (delay, true,
2541 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on measurement channel width
2542 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2543 succ, fail, bytes);
2544 delay += Seconds (1.0);
2545
2546 //---------------------------------------------------------------------------
2547 //Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both unsolicited HE TB PPDUs have been impacted if they are on the same
2548 // 20 MHz channel. Only STA 1's unsolicited HE TB PPDU is impacted otherwise.
2549 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2550 "Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
2551 //Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
2552 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
2553 ScheduleTest (delay, false,
2554 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on primary channel width
2555 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2556 succ, fail, bytes); //same as solicited case
2557 delay += Seconds (1.0);
2558
2559 //---------------------------------------------------------------------------
2560 //Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both solicited HE TB PPDUs have been impacted if they are on the same
2561 // 20 MHz channel. Only STA 2's solicited HE TB PPDU is impacted otherwise.
2562 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2563 "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU 2 during PSDU reception");
2564 //Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
2565 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
2566 //Expected figures from STA 1
2567 if (m_channelWidth > 20)
2568 {
2569 //One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference from STA 3 on distinct 20 MHz channel)
2570 succ = 1;
2571 fail = 0;
2572 bytes = 1000;
2573 }
2574 else
2575 {
2576 //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2577 succ = 0;
2578 fail = 1;
2579 bytes = 0;
2580 }
2581 ScheduleTest (delay, true,
2582 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on measurement channel width
2583 succ, fail, bytes,
2584 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2585 delay += Seconds (1.0);
2586
2587 //---------------------------------------------------------------------------
2588 //Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both unsolicited HE TB PPDUs have been impacted if they are on the same
2589 // 20 MHz channel. Only STA 2's unsolicited HE TB PPDU is impacted otherwise.
2590 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2591 "Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU2 during payload reception");
2592 //Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
2593 Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
2594 ScheduleTest (delay, false,
2595 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
2596 succ, fail, bytes, //same as solicited case
2597 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2598 delay += Seconds (1.0);
2599
2600 //---------------------------------------------------------------------------
2601 //Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
2602 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2603 "Reception of solicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
2604 //One HE SU arrives at AP during the 400ns window
2605 Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
2606 ScheduleTest (delay, true,
2607 WifiPhyState::IDLE,
2608 0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3)
2609 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3)
2610 delay += Seconds (1.0);
2611
2612 //---------------------------------------------------------------------------
2613 //Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
2614 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2615 "Reception of unsolicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
2616 //One HE SU arrives at AP during the 400ns window
2617 Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
2618 ScheduleTest (delay, false,
2619 WifiPhyState::IDLE,
2620 0, 1, 0, //Reception of the PSDU from STA 1 should have failed failed (since interference from STA 3)
2621 0, 1, 0); //Reception of the PSDU from STA 2 should have failed failed (since interference from STA 3)
2622 delay += Seconds (1.0);
2623
2624 //---------------------------------------------------------------------------
2625 //Only send a solicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received
2626 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2627 "Reception of solicited HE TB PPDU only on RU 2");
2628 //Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
2629 Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
2630 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
2631 ScheduleTest (delay, true,
2632 WifiPhyState::IDLE,
2633 0, 0, 0, //No transmission scheduled for STA 1
2634 1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2635 false, WifiPhyState::RX); //Measurement channel is total channel width
2636 delay += Seconds (1.0);
2637
2638 //---------------------------------------------------------------------------
2639 //Only send an unsolicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received if it's in the
2640 // correct measurement channel
2641 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2642 "Reception of unsolicited HE TB PPDUs only on RU 2");
2643 //Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
2644 Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
2645 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
2646 //Expected figures from STA 2
2647 WifiPhyState state;
2648 if (m_channelWidth == 20)
2649 {
2650 //One PSDU of 1001 bytes should have been successfully received from STA 2 (since measurement channel is primary channel)
2651 succ = 1;
2652 fail = 0;
2653 bytes = 1001;
2654 state = WifiPhyState::RX;
2655 }
2656 else
2657 {
2658 //No PSDU should have been received from STA 2 (since measurement channel is primary channel)
2659 succ = 0;
2660 fail = 0;
2661 bytes = 0;
2662 state = WifiPhyState::IDLE;
2663 }
2664 ScheduleTest (delay, false,
2665 WifiPhyState::IDLE,
2666 0, 0, 0, //No transmission scheduled for STA 1
2667 succ, fail, bytes,
2668 false, state);
2669 delay += Seconds (1.0);
2670
2671 //---------------------------------------------------------------------------
2672 //Measure the power of a solicited HE TB PPDU from STA 2 on RU 2
2673 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2674 "Measure power for reception of HE TB PPDU only on RU 2");
2675 double rxPower = DbmToW (19); //16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
2676 SchedulePowerMeasurementChecks (delay,
2677 (m_channelWidth >= 40) ? 0.0 : rxPower, rxPower, //power detected on RU1 only if same 20 MHz as RU 2
2678 0.0, rxPower);
2679 ScheduleTest (delay, true,
2680 WifiPhyState::IDLE,
2681 0, 0, 0, //No transmission scheduled for STA 1
2682 1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2683 false, WifiPhyState::RX); //Measurement channel is total channel width
2684 delay += Seconds (1.0);
2685
2686 //---------------------------------------------------------------------------
2687 //Measure the power of a solicited HE TB PPDU from STA 2 on RU 2 with power spectrum density limitation enforced
2688 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2689 "Measure power for reception of HE TB PPDU only on RU 2 with PSD limitation");
2690 //Configure PSD limitation at 3 dBm/MHz -> 3+13.0103=16.0103 dBm max for 20 MHz, 3+9.0309=12.0309 dBm max for 106-tone RU, no impact for 40 MHz and above
2691 Simulator::Schedule (delay - NanoSeconds (1), //just before sending HE TB
2692 &TestUlOfdmaPhyTransmission::SetPsdLimit, this, m_phySta2, 3.0);
2693
2694 rxPower = (m_channelWidth > 40) ? DbmToW (19) : DbmToW (18.0103); //15.0103+1 dBm at STA 2 and +2 at AP for non-OFDMA transmitted only on one 20 MHz channel
2695 double rxPowerOfdma = rxPower;
2696 if (m_channelWidth <= 40)
2697 {
2698 rxPowerOfdma = (m_channelWidth == 20) ? DbmToW (14.0309) //11.0309+1 dBm at STA and +2 at AP if 106-tone RU
2699 : DbmToW (18.0103); //15.0103+1 dBm at STA 2 and +2 at AP if 242-tone RU
2700 }
2701 SchedulePowerMeasurementChecks (delay,
2702 (m_channelWidth >= 40) ? 0.0 : rxPower, rxPower, //power detected on RU1 only if same 20 MHz as RU 2
2703 0.0, rxPowerOfdma);
2704
2705 //Reset PSD limitation once HE TB has been sent
2706 Simulator::Schedule (delay + m_expectedPpduDuration,
2707 &TestUlOfdmaPhyTransmission::SetPsdLimit, this, m_phySta2, 100.0);
2708 ScheduleTest (delay, true,
2709 WifiPhyState::IDLE,
2710 0, 0, 0, //No transmission scheduled for STA 1
2711 1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2712 false, WifiPhyState::RX); //Measurement channel is total channel width
2713 delay += Seconds (1.0);
2714
2715 //---------------------------------------------------------------------------
2716 //Measure the power of 2 solicited HE TB PPDU from both STAs
2717 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2718 "Measure power for reception of HE TB PPDU on both RUs");
2719 rxPower = DbmToW (19); //16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
2720 double rxPowerNonOfdma = (m_channelWidth >= 40) ? rxPower : rxPower * 2; //both STAs transmit over the same 20 MHz channel
2721 SchedulePowerMeasurementChecks (delay,
2722 rxPowerNonOfdma, rxPowerNonOfdma,
2723 rxPower, rxPower);
2724 ScheduleTest (delay, true,
2725 WifiPhyState::IDLE,
2726 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2727 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2728 delay += Seconds (1.0);
2729
2730 //---------------------------------------------------------------------------
2731 //Verify that an HE SU PPDU from another BSS has been correctly received (no UL MU transmission ongoing)
2732 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2733 "Reception of an HE SU PPDU from another BSS");
2734 //One HE SU from another BSS (BSS color 2) arrives at AP (BSS color 1)
2735 Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SetBssColor, this, m_phyAp, 1);
2736 Simulator::Schedule (delay + MilliSeconds (100), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 2);
2737
2738 //Verify events data have been cleared
2739 Simulator::Schedule (delay + MilliSeconds (200), &TestUlOfdmaPhyTransmission::VerifyEventsCleared, this);
2740
2741 Simulator::Schedule (delay + MilliSeconds (500), &TestUlOfdmaPhyTransmission::Reset, this);
2742 delay += Seconds (1.0);
2743
2744 Simulator::Run ();
2745 }
2746
2747 void
DoRun(void)2748 TestUlOfdmaPhyTransmission::DoRun (void)
2749 {
2750 m_frequency = 5180;
2751 m_channelWidth = 20;
2752 m_expectedPpduDuration = NanoSeconds (279200);
2753 NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2754 RunOne ();
2755
2756 m_frequency = 5190;
2757 m_channelWidth = 40;
2758 m_expectedPpduDuration = NanoSeconds (156800);
2759 NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2760 RunOne ();
2761
2762 m_frequency = 5210;
2763 m_channelWidth = 80;
2764 m_expectedPpduDuration = NanoSeconds (102400);
2765 NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2766 RunOne ();
2767
2768 m_frequency = 5250;
2769 m_channelWidth = 160;
2770 m_expectedPpduDuration = NanoSeconds (75200);
2771 NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2772 RunOne ();
2773
2774 Simulator::Destroy ();
2775 }
2776
2777 /**
2778 * \ingroup wifi-test
2779 * \ingroup tests
2780 *
2781 * \brief PHY padding exclusion test
2782 */
2783 class TestPhyPaddingExclusion : public TestCase
2784 {
2785 public:
2786 TestPhyPaddingExclusion ();
2787 virtual ~TestPhyPaddingExclusion ();
2788
2789 private:
2790 void DoSetup (void) override;
2791 void DoTeardown (void) override;
2792 void DoRun (void) override;
2793
2794 /**
2795 * Send HE TB PPDU function
2796 * \param txStaId the ID of the TX STA
2797 * \param index the RU index used for the transmission
2798 * \param payloadSize the size of the payload in bytes
2799 * \param txDuration the duration of the PPDU
2800 */
2801 void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration);
2802
2803 /**
2804 * Generate interference function
2805 * \param interferencePsd the PSD of the interference to be generated
2806 * \param duration the duration of the interference
2807 */
2808 void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
2809 /**
2810 * Stop interference function
2811 */
2812 void StopInterference (void);
2813
2814 /**
2815 * Run one function
2816 */
2817 void RunOne ();
2818
2819 /**
2820 * Check the received PSDUs from STA1
2821 * \param expectedSuccess the expected number of success
2822 * \param expectedFailures the expected number of failures
2823 * \param expectedBytes the expected number of bytes
2824 */
2825 void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2826
2827 /**
2828 * Check the received PSDUs from STA2
2829 * \param expectedSuccess the expected number of success
2830 * \param expectedFailures the expected number of failures
2831 * \param expectedBytes the expected number of bytes
2832 */
2833 void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2834
2835 /**
2836 * Verify all events are cleared at end of TX or RX
2837 */
2838 void VerifyEventsCleared (void);
2839
2840 /**
2841 * Check the PHY state
2842 * \param phy the PHY
2843 * \param expectedState the expected state of the PHY
2844 */
2845 void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
2846 /// \copydoc CheckPhyState
2847 void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
2848
2849 /**
2850 * Reset function
2851 */
2852 void Reset ();
2853
2854 /**
2855 * Receive success function
2856 * \param psdu the PSDU
2857 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
2858 * \param txVector the transmit vector
2859 * \param statusPerMpdu reception status per MPDU
2860 */
2861 void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
2862
2863 /**
2864 * Receive failure function
2865 * \param psdu the PSDU
2866 */
2867 void RxFailure (Ptr<WifiPsdu> psdu);
2868
2869 Ptr<OfdmaSpectrumWifiPhy> m_phyAp; ///< PHY of AP
2870 Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
2871 Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
2872
2873 Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
2874
2875 uint32_t m_countRxSuccessFromSta1; ///< count RX success from STA 1
2876 uint32_t m_countRxSuccessFromSta2; ///< count RX success from STA 2
2877 uint32_t m_countRxFailureFromSta1; ///< count RX failure from STA 1
2878 uint32_t m_countRxFailureFromSta2; ///< count RX failure from STA 2
2879 uint32_t m_countRxBytesFromSta1; ///< count RX bytes from STA 1
2880 uint32_t m_countRxBytesFromSta2; ///< count RX bytes from STA 2
2881 };
2882
TestPhyPaddingExclusion()2883 TestPhyPaddingExclusion::TestPhyPaddingExclusion ()
2884 : TestCase ("PHY padding exclusion test"),
2885 m_countRxSuccessFromSta1 (0),
2886 m_countRxSuccessFromSta2 (0),
2887 m_countRxFailureFromSta1 (0),
2888 m_countRxFailureFromSta2 (0),
2889 m_countRxBytesFromSta1 (0),
2890 m_countRxBytesFromSta2 (0)
2891 {
2892 }
2893
2894 void
SendHeTbPpdu(uint16_t txStaId,std::size_t index,std::size_t payloadSize,Time txDuration)2895 TestPhyPaddingExclusion::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration)
2896 {
2897 WifiConstPsduMap psdus;
2898
2899 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false, 1);
2900
2901 HeRu::RuSpec ru (HeRu::RU_106_TONE, index, false);
2902 txVector.SetRu (ru, txStaId);
2903 txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
2904 txVector.SetNss (1, txStaId);
2905
2906 Ptr<Packet> pkt = Create<Packet> (payloadSize);
2907 WifiMacHeader hdr;
2908 hdr.SetType (WIFI_MAC_QOSDATA);
2909 hdr.SetQosTid (0);
2910 hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
2911 std::ostringstream addr;
2912 addr << "00:00:00:00:00:0" << txStaId;
2913 hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
2914 hdr.SetSequenceNumber (1);
2915 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
2916 psdus.insert (std::make_pair (txStaId, psdu));
2917
2918 Ptr<OfdmaSpectrumWifiPhy> phy;
2919 if (txStaId == 1)
2920 {
2921 phy = m_phySta1;
2922 }
2923 else if (txStaId == 2)
2924 {
2925 phy = m_phySta2;
2926 }
2927
2928 txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
2929
2930 phy->SetPpduUid (0);
2931 phy->Send (psdus, txVector);
2932 }
2933
2934 void
GenerateInterference(Ptr<SpectrumValue> interferencePsd,Time duration)2935 TestPhyPaddingExclusion::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
2936 {
2937 m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
2938 m_phyInterferer->SetPeriod (duration);
2939 m_phyInterferer->Start ();
2940 Simulator::Schedule (duration, &TestPhyPaddingExclusion::StopInterference, this);
2941 }
2942
2943 void
StopInterference(void)2944 TestPhyPaddingExclusion::StopInterference (void)
2945 {
2946 m_phyInterferer->Stop();
2947 }
2948
~TestPhyPaddingExclusion()2949 TestPhyPaddingExclusion::~TestPhyPaddingExclusion ()
2950 {
2951 }
2952
2953 void
RxSuccess(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)2954 TestPhyPaddingExclusion::RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
2955 {
2956 NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << rxSignalInfo << txVector);
2957 if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2958 {
2959 m_countRxSuccessFromSta1++;
2960 m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
2961 }
2962 else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2963 {
2964 m_countRxSuccessFromSta2++;
2965 m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
2966 }
2967 }
2968
2969 void
RxFailure(Ptr<WifiPsdu> psdu)2970 TestPhyPaddingExclusion::RxFailure (Ptr<WifiPsdu> psdu)
2971 {
2972 NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2973 if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2974 {
2975 m_countRxFailureFromSta1++;
2976 }
2977 else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2978 {
2979 m_countRxFailureFromSta2++;
2980 }
2981 }
2982
2983 void
CheckRxFromSta1(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2984 TestPhyPaddingExclusion::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2985 {
2986 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
2987 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
2988 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
2989 }
2990
2991 void
CheckRxFromSta2(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2992 TestPhyPaddingExclusion::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2993 {
2994 NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
2995 NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
2996 NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
2997 }
2998
2999 void
VerifyEventsCleared(void)3000 TestPhyPaddingExclusion::VerifyEventsCleared (void)
3001 {
3002 NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
3003 NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
3004 NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
3005 }
3006
3007 void
CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)3008 TestPhyPaddingExclusion::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
3009 {
3010 //This is needed to make sure PHY state will be checked as the last event if a state change occurred at the exact same time as the check
3011 Simulator::ScheduleNow (&TestPhyPaddingExclusion::DoCheckPhyState, this, phy, expectedState);
3012 }
3013
3014 void
DoCheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)3015 TestPhyPaddingExclusion::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
3016 {
3017 WifiPhyState currentState = phy->GetState ()->GetState ();
3018 NS_LOG_FUNCTION (this << currentState);
3019 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
3020 }
3021
3022 void
Reset(void)3023 TestPhyPaddingExclusion::Reset (void)
3024 {
3025 m_countRxSuccessFromSta1 = 0;
3026 m_countRxSuccessFromSta2 = 0;
3027 m_countRxFailureFromSta1 = 0;
3028 m_countRxFailureFromSta2 = 0;
3029 m_countRxBytesFromSta1 = 0;
3030 m_countRxBytesFromSta2 = 0;
3031 m_phySta1->SetPpduUid (0);
3032 m_phySta1->SetTriggerFrameUid (0);
3033 m_phySta2->SetTriggerFrameUid (0);
3034 }
3035
3036 void
DoSetup(void)3037 TestPhyPaddingExclusion::DoSetup (void)
3038 {
3039 RngSeedManager::SetSeed (1);
3040 RngSeedManager::SetRun (1);
3041 int64_t streamNumber = 0;
3042
3043 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
3044 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
3045 lossModel->SetFrequency (DEFAULT_FREQUENCY * 1e6);
3046 spectrumChannel->AddPropagationLossModel (lossModel);
3047 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
3048 spectrumChannel->SetPropagationDelayModel (delayModel);
3049
3050 Ptr<Node> apNode = CreateObject<Node> ();
3051 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
3052 Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
3053 apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
3054 apDev->SetMac (apMac);
3055 m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
3056 m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
3057 m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
3058 Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
3059 apDev->SetHeConfiguration (heConfiguration);
3060 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
3061 m_phyAp->SetErrorRateModel (error);
3062 m_phyAp->SetDevice (apDev);
3063 m_phyAp->SetChannel (spectrumChannel);
3064 m_phyAp->AssignStreams (streamNumber);
3065 m_phyAp->SetFrequency (DEFAULT_FREQUENCY);
3066 m_phyAp->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
3067 m_phyAp->SetReceiveOkCallback (MakeCallback (&TestPhyPaddingExclusion::RxSuccess, this));
3068 m_phyAp->SetReceiveErrorCallback (MakeCallback (&TestPhyPaddingExclusion::RxFailure, this));
3069 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
3070 m_phyAp->SetMobility (apMobility);
3071 apDev->SetPhy (m_phyAp);
3072 apNode->AggregateObject (apMobility);
3073 apNode->AddDevice (apDev);
3074
3075 Ptr<Node> sta1Node = CreateObject<Node> ();
3076 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
3077 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
3078 m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
3079 m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
3080 m_phySta1->SetErrorRateModel (error);
3081 m_phySta1->SetDevice (sta1Dev);
3082 m_phySta1->SetChannel (spectrumChannel);
3083 m_phySta1->AssignStreams (streamNumber);
3084 m_phySta1->SetFrequency (DEFAULT_FREQUENCY);
3085 m_phySta1->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
3086 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
3087 m_phySta1->SetMobility (sta1Mobility);
3088 sta1Dev->SetPhy (m_phySta1);
3089 sta1Node->AggregateObject (sta1Mobility);
3090 sta1Node->AddDevice (sta1Dev);
3091
3092 Ptr<Node> sta2Node = CreateObject<Node> ();
3093 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
3094 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
3095 m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
3096 m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
3097 m_phySta2->SetErrorRateModel (error);
3098 m_phySta2->SetDevice (sta2Dev);
3099 m_phySta2->SetChannel (spectrumChannel);
3100 m_phySta2->AssignStreams (streamNumber);
3101 m_phySta2->SetFrequency (DEFAULT_FREQUENCY);
3102 m_phySta2->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
3103 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
3104 m_phySta2->SetMobility (sta2Mobility);
3105 sta2Dev->SetPhy (m_phySta2);
3106 sta2Node->AggregateObject (sta2Mobility);
3107 sta2Node->AddDevice (sta2Dev);
3108
3109 Ptr<Node> interfererNode = CreateObject<Node> ();
3110 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
3111 m_phyInterferer = CreateObject<WaveformGenerator> ();
3112 m_phyInterferer->SetDevice (interfererDev);
3113 m_phyInterferer->SetChannel (spectrumChannel);
3114 m_phyInterferer->SetDutyCycle (1);
3115 interfererNode->AddDevice (interfererDev);
3116 }
3117
3118 void
DoTeardown(void)3119 TestPhyPaddingExclusion::DoTeardown (void)
3120 {
3121 m_phyAp->Dispose ();
3122 m_phyAp = 0;
3123 m_phySta1->Dispose ();
3124 m_phySta1 = 0;
3125 m_phySta2->Dispose ();
3126 m_phySta2 = 0;
3127 m_phyInterferer->Dispose ();
3128 m_phyInterferer = 0;
3129 }
3130
3131 void
DoRun(void)3132 TestPhyPaddingExclusion::DoRun (void)
3133 {
3134 Time expectedPpduDuration = NanoSeconds (279200);
3135 Time ppduWithPaddingDuration = expectedPpduDuration + 10 * NanoSeconds (12800 + 800 /* GI */); //add 10 extra OFDM symbols
3136
3137 Simulator::Schedule (Seconds (0.0), &TestPhyPaddingExclusion::Reset, this);
3138
3139 //STA1 and STA2 send MU UL PPDUs addressed to AP:
3140 Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
3141 Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
3142
3143 //Verify it takes expectedPpduDuration + padding to transmit the PPDUs
3144 Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
3145 Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::IDLE);
3146
3147 //One PSDU of 1000 bytes should have been successfully received from STA 1
3148 Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
3149 //One PSDU of 1001 bytes should have been successfully received from STA 2
3150 Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
3151 //Verify events data have been cleared
3152 Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
3153
3154 Simulator::Schedule (Seconds (1.5), &TestPhyPaddingExclusion::Reset, this);
3155
3156
3157 //STA1 and STA2 send MU UL PPDUs addressed to AP:
3158 Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
3159 Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
3160
3161 //A strong non-wifi interference is generated on RU 1 during padding reception
3162 BandInfo bandInfo;
3163 bandInfo.fc = (DEFAULT_FREQUENCY - (DEFAULT_CHANNEL_WIDTH / 4)) * 1e6;
3164 bandInfo.fl = bandInfo.fc - ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
3165 bandInfo.fh = bandInfo.fc + ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
3166 Bands bands;
3167 bands.push_back (bandInfo);
3168
3169 Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
3170 Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
3171 double interferencePower = 0.1; //watts
3172 *interferencePsdRu1 = interferencePower / ((DEFAULT_CHANNEL_WIDTH / 2) * 20e6);
3173
3174 Simulator::Schedule (Seconds (2.0) + MicroSeconds (50) + expectedPpduDuration, &TestPhyPaddingExclusion::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
3175
3176 //Verify it takes expectedPpduDuration + padding to transmit the PPDUs (PHY should move to CCA_BUSY instead of IDLE due to the interference)
3177 Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
3178 Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::CCA_BUSY);
3179
3180 //One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference occupies RU 1 after payload, during PHY padding)
3181 Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
3182 //One PSDU of 1001 bytes should have been successfully received from STA 2
3183 Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
3184 //Verify events data have been cleared
3185 Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
3186
3187 Simulator::Schedule (Seconds (2.5), &TestPhyPaddingExclusion::Reset, this);
3188
3189 Simulator::Run ();
3190
3191 Simulator::Destroy ();
3192 }
3193
3194 /**
3195 * \ingroup wifi-test
3196 * \ingroup tests
3197 *
3198 * \brief UL-OFDMA power control test
3199 */
3200 class TestUlOfdmaPowerControl : public TestCase
3201 {
3202 public:
3203 TestUlOfdmaPowerControl ();
3204 virtual ~TestUlOfdmaPowerControl ();
3205
3206 private:
3207 void DoSetup (void) override;
3208 void DoTeardown (void) override;
3209 void DoRun (void) override;
3210
3211 /**
3212 * Send a MU BAR through the AP to the STAs listed in the provided vector.
3213 *
3214 * \param staIds the vector of STA-IDs of STAs to address the MU-BAR to
3215 */
3216 void SendMuBar (std::vector <uint16_t> staIds);
3217
3218 /**
3219 * Send a QoS Data packet to the destination station in order
3220 * to set up a block Ack session (so that the MU-BAR may have a reply).
3221 *
3222 * \param destination the address of the destination station
3223 */
3224 void SetupBa (Address destination);
3225
3226 /**
3227 * Run one simulation with an optional BA session set up phase.
3228 *
3229 * \param setupBa true if BA session should be set up (i.e. upon first run),
3230 * false otherwise
3231 */
3232 void RunOne (bool setupBa);
3233
3234 /**
3235 * Replace the AP's callback on its PHY's ReceiveOkCallback
3236 * by the ReceiveOkCallbackAtAp method.
3237 */
3238 void ReplaceReceiveOkCallbackOfAp (void);
3239
3240 /**
3241 * Receive OK callback function at AP.
3242 * This method will be plugged into the AP PHY's ReceiveOkCallback once the
3243 * block Ack session has been set up. This is done in the Reset function.
3244 * \param psdu the PSDU
3245 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
3246 * \param txVector the TXVECTOR used for the packet
3247 * \param statusPerMpdu reception status per MPDU
3248 */
3249 void ReceiveOkCallbackAtAp (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
3250 WifiTxVector txVector, std::vector<bool> statusPerMpdu);
3251
3252 uint8_t m_bssColor; ///< BSS color
3253
3254 Ptr<WifiNetDevice> m_apDev; ///< network device of AP
3255 Ptr<WifiNetDevice> m_sta1Dev; ///< network device of STA 1
3256 Ptr<WifiNetDevice> m_sta2Dev; ///< network device of STA 2
3257
3258 Ptr<SpectrumWifiPhy> m_phyAp; ///< PHY of AP
3259
3260 double m_txPowerAp; ///< transmit power (in dBm) of AP
3261 double m_txPowerStart; ///< minimum transmission power (in dBm) for STAs
3262 double m_txPowerEnd; ///< maximum transmission power (in dBm) for STAs
3263 uint8_t m_txPowerLevels; ///< number of transmission power levels for STAs
3264
3265 double m_requestedRssiSta1; ///< requested RSSI (in dBm) from STA 1 at AP for HE TB PPDUs
3266 double m_requestedRssiSta2; ///< requested RSSI (in dBm) from STA 2 at AP for HE TB PPDUs
3267
3268 double m_rssiSta1; ///< expected RSSI (in dBm) from STA 1 at AP for HE TB PPDUs
3269 double m_rssiSta2; ///< expected RSSI (in dBm) from STA 2 at AP for HE TB PPDUs
3270
3271 double m_tol; ///< tolerance (in dB) between received and expected RSSIs
3272 };
3273
TestUlOfdmaPowerControl()3274 TestUlOfdmaPowerControl::TestUlOfdmaPowerControl ()
3275 : TestCase ("UL-OFDMA power control test"),
3276 m_bssColor (1),
3277 m_txPowerAp (0),
3278 m_txPowerStart (0),
3279 m_txPowerEnd (0),
3280 m_txPowerLevels (0),
3281 m_requestedRssiSta1 (0),
3282 m_requestedRssiSta2 (0),
3283 m_rssiSta1 (0),
3284 m_rssiSta2 (0),
3285 m_tol (0.1)
3286 {
3287 }
3288
~TestUlOfdmaPowerControl()3289 TestUlOfdmaPowerControl::~TestUlOfdmaPowerControl ()
3290 {
3291 m_phyAp = 0;
3292 m_apDev = 0;
3293 m_sta1Dev = 0;
3294 m_sta2Dev = 0;
3295 }
3296
3297 void
SetupBa(Address destination)3298 TestUlOfdmaPowerControl::SetupBa (Address destination)
3299 {
3300 //Only one packet is sufficient to set up BA since AP and STAs are HE capable
3301 Ptr<Packet> pkt = Create<Packet> (100); // 100 dummy bytes of data
3302 m_apDev->Send (pkt, destination, 0);
3303 }
3304
3305 void
SendMuBar(std::vector<uint16_t> staIds)3306 TestUlOfdmaPowerControl::SendMuBar (std::vector <uint16_t> staIds)
3307 {
3308 NS_ASSERT (!staIds.empty () && staIds.size () <= 2);
3309
3310 //Build MU-BAR trigger frame
3311 CtrlTriggerHeader muBar;
3312 muBar.SetType (MU_BAR_TRIGGER);
3313 muBar.SetUlLength (HePhy::ConvertHeTbPpduDurationToLSigLength (MicroSeconds (128), WIFI_PHY_BAND_5GHZ));
3314 muBar.SetMoreTF (true);
3315 muBar.SetCsRequired (true);
3316 muBar.SetUlBandwidth (DEFAULT_CHANNEL_WIDTH);
3317 muBar.SetGiAndLtfType (1600, 2);
3318 muBar.SetApTxPower (static_cast<int8_t> (m_txPowerAp));
3319 muBar.SetUlSpatialReuse (60500);
3320
3321 HeRu::RuType ru = (staIds.size () == 1) ? HeRu::RU_242_TONE : HeRu::RU_106_TONE;
3322 std::size_t index = 1;
3323 int8_t ulTargetRssi = -40; //will be overwritten
3324 for (auto const& staId : staIds)
3325 {
3326 CtrlTriggerUserInfoField& ui = muBar.AddUserInfoField ();
3327 ui.SetAid12 (staId);
3328 ui.SetRuAllocation ({ru, index, true});
3329 ui.SetUlFecCodingType (true);
3330 ui.SetUlMcs (7);
3331 ui.SetUlDcm (false);
3332 ui.SetSsAllocation (1, 1);
3333 if (staId == 1)
3334 {
3335 ulTargetRssi = m_requestedRssiSta1;
3336 }
3337 else if (staId == 2)
3338 {
3339 ulTargetRssi = m_requestedRssiSta2;
3340 }
3341 else
3342 {
3343 NS_ABORT_MSG ("Unknown STA-ID (" << staId << ")");
3344 }
3345 ui.SetUlTargetRssi (ulTargetRssi);
3346
3347 CtrlBAckRequestHeader bar;
3348 bar.SetType (BlockAckReqType::COMPRESSED);
3349 bar.SetTidInfo (0);
3350 bar.SetStartingSequence (4095);
3351 ui.SetMuBarTriggerDepUserInfo (bar);
3352
3353 ++index;
3354 }
3355
3356 WifiConstPsduMap psdus;
3357 WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0,
3358 DEFAULT_CHANNEL_WIDTH, false, false, false, m_bssColor);
3359
3360 Ptr<Packet> bar = Create<Packet> ();
3361 bar->AddHeader (muBar);
3362
3363 Mac48Address receiver = Mac48Address::GetBroadcast ();
3364 if (staIds.size () == 1)
3365 {
3366 uint16_t aidSta1 = DynamicCast<StaWifiMac> (m_sta1Dev->GetMac ())->GetAssociationId ();
3367 if (staIds.front () == aidSta1)
3368 {
3369 receiver = Mac48Address::ConvertFrom (m_sta1Dev->GetAddress ());
3370 }
3371 else
3372 {
3373 NS_ASSERT (staIds.front () == DynamicCast<StaWifiMac> (m_sta2Dev->GetMac ())->GetAssociationId ());
3374 receiver = Mac48Address::ConvertFrom (m_sta2Dev->GetAddress ());
3375 }
3376 }
3377
3378 WifiMacHeader hdr;
3379 hdr.SetType (WIFI_MAC_CTL_TRIGGER);
3380 hdr.SetAddr1 (receiver);
3381 hdr.SetAddr2 (Mac48Address::ConvertFrom (m_apDev->GetAddress ()));
3382 hdr.SetAddr3 (Mac48Address::ConvertFrom (m_apDev->GetAddress ()));
3383 hdr.SetDsNotTo ();
3384 hdr.SetDsFrom ();
3385 hdr.SetNoRetry ();
3386 hdr.SetNoMoreFragments ();
3387 Ptr<WifiPsdu> psdu = Create<WifiPsdu> (bar, hdr);
3388
3389 Time nav = m_apDev->GetPhy ()->GetSifs ();
3390 uint16_t staId = staIds.front (); //either will do
3391 nav += m_phyAp->CalculateTxDuration (GetBlockAckSize (BlockAckType::COMPRESSED), muBar.GetHeTbTxVector (staId), DEFAULT_WIFI_BAND, staId);
3392 psdu->SetDuration (nav);
3393 psdus.insert (std::make_pair (SU_STA_ID, psdu));
3394
3395 m_phyAp->Send (psdus, txVector);
3396 }
3397
3398 void
ReceiveOkCallbackAtAp(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)3399 TestUlOfdmaPowerControl::ReceiveOkCallbackAtAp (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
3400 WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
3401 {
3402 NS_TEST_ASSERT_MSG_EQ (txVector.GetPreambleType (), WIFI_PREAMBLE_HE_TB, "HE TB PPDU expected");
3403 double rssi = rxSignalInfo.rssi;
3404 NS_ASSERT (psdu->GetNMpdus () == 1);
3405 WifiMacHeader hdr = psdu->GetHeader (0);
3406 NS_TEST_ASSERT_MSG_EQ (hdr.GetType (), WIFI_MAC_CTL_BACKRESP, "Block ACK expected");
3407 if (hdr.GetAddr2 () == m_sta1Dev->GetAddress ())
3408 {
3409 NS_TEST_ASSERT_MSG_EQ_TOL (rssi, m_rssiSta1, m_tol, "The obtained RSSI from STA 1 at AP is different from the expected one (" << rssi << " vs " << m_rssiSta1 << ", with tolerance of " << m_tol << ")");
3410 }
3411 else if (psdu->GetAddr2 () == m_sta2Dev->GetAddress ())
3412 {
3413 NS_TEST_ASSERT_MSG_EQ_TOL (rssi, m_rssiSta2, m_tol, "The obtained RSSI from STA 2 at AP is different from the expected one (" << rssi << " vs " << m_rssiSta2 << ", with tolerance of " << m_tol << ")");
3414 }
3415 else
3416 {
3417 NS_ABORT_MSG ("The receiver address is unknown");
3418 }
3419 }
3420
3421 void
ReplaceReceiveOkCallbackOfAp(void)3422 TestUlOfdmaPowerControl::ReplaceReceiveOkCallbackOfAp (void)
3423 {
3424 //Now that BA session has been established we can plug our method
3425 m_phyAp->SetReceiveOkCallback (MakeCallback (&TestUlOfdmaPowerControl::ReceiveOkCallbackAtAp, this));
3426 }
3427
3428 void
DoSetup(void)3429 TestUlOfdmaPowerControl::DoSetup (void)
3430 {
3431 Ptr<Node> apNode = CreateObject<Node> ();
3432 NodeContainer staNodes;
3433 staNodes.Create (2);
3434
3435 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
3436 Ptr<MatrixPropagationLossModel> lossModel = CreateObject<MatrixPropagationLossModel> ();
3437 spectrumChannel->AddPropagationLossModel (lossModel);
3438 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
3439 spectrumChannel->SetPropagationDelayModel (delayModel);
3440
3441 SpectrumWifiPhyHelper spectrumPhy;
3442 spectrumPhy.SetChannel (spectrumChannel);
3443 spectrumPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
3444 spectrumPhy.Set ("Frequency", UintegerValue (DEFAULT_FREQUENCY));
3445 spectrumPhy.Set ("ChannelWidth", UintegerValue (DEFAULT_CHANNEL_WIDTH));
3446
3447 WifiHelper wifi;
3448 wifi.SetStandard (WIFI_STANDARD_80211ax_5GHZ);
3449 wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
3450 "DataMode", StringValue ("HeMcs7"),
3451 "ControlMode", StringValue ("HeMcs7"));
3452
3453 WifiMacHelper mac;
3454 mac.SetType ("ns3::StaWifiMac");
3455 NetDeviceContainer staDevs = wifi.Install (spectrumPhy, mac, staNodes);
3456 wifi.AssignStreams (staDevs, 0);
3457 m_sta1Dev = DynamicCast<WifiNetDevice> (staDevs.Get (0));
3458 NS_ASSERT (m_sta1Dev);
3459 m_sta2Dev = DynamicCast<WifiNetDevice> (staDevs.Get (1));
3460 NS_ASSERT (m_sta2Dev);
3461
3462 //Set the beacon interval long enough so that associated STAs may not consider link lost when
3463 //beacon generation is disabled during the actual tests. Having such a long interval also
3464 //avoids bloating logs with beacons during the set up phase.
3465 mac.SetType ("ns3::ApWifiMac",
3466 "BeaconGeneration", BooleanValue (true),
3467 "BeaconInterval", TimeValue (MicroSeconds (1024 * 600)));
3468 m_apDev = DynamicCast<WifiNetDevice> (wifi.Install (spectrumPhy, mac, apNode).Get (0));
3469 NS_ASSERT (m_apDev);
3470 m_apDev->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (m_bssColor));
3471 m_phyAp = DynamicCast<SpectrumWifiPhy> (m_apDev->GetPhy ());
3472 NS_ASSERT (m_phyAp);
3473 //ReceiveOkCallback of AP will be set to corresponding test's method once BA sessions have been set up for both STAs
3474
3475 MobilityHelper mobility;
3476 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
3477 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
3478 positionAlloc->Add (Vector (0.0, 0.0, 0.0));
3479 positionAlloc->Add (Vector (1.0, 0.0, 0.0)); // put close enough in order to use MCS
3480 positionAlloc->Add (Vector (2.0, 0.0, 0.0)); // STA 2 is a bit further away, but still in range of MCS
3481 mobility.SetPositionAllocator (positionAlloc);
3482
3483 mobility.Install (apNode);
3484 mobility.Install (staNodes);
3485
3486 lossModel->SetDefaultLoss (50.0);
3487 lossModel->SetLoss (apNode->GetObject<MobilityModel> (), staNodes.Get (1)->GetObject<MobilityModel> (),
3488 56.0, true); //+6 dB between AP <-> STA 2 compared to AP <-> STA 1
3489 }
3490
3491 void
DoTeardown(void)3492 TestUlOfdmaPowerControl::DoTeardown (void)
3493 {
3494 m_phyAp->Dispose ();
3495 m_phyAp = 0;
3496 m_apDev->Dispose ();
3497 m_apDev = 0;
3498 m_sta1Dev->Dispose ();
3499 m_sta1Dev = 0;
3500 m_sta2Dev->Dispose ();
3501 m_sta2Dev = 0;
3502 }
3503
3504 void
RunOne(bool setupBa)3505 TestUlOfdmaPowerControl::RunOne (bool setupBa)
3506 {
3507 RngSeedManager::SetSeed (1);
3508 RngSeedManager::SetRun (1);
3509 int64_t streamNumber = 0;
3510
3511 Ptr<WifiPhy> phySta1 = m_sta1Dev->GetPhy ();
3512 Ptr<WifiPhy> phySta2 = m_sta2Dev->GetPhy ();
3513
3514 m_phyAp->AssignStreams (streamNumber);
3515 phySta1->AssignStreams (streamNumber);
3516 phySta2->AssignStreams (streamNumber);
3517
3518 m_phyAp->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerAp));
3519 m_phyAp->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerAp));
3520 m_phyAp->SetAttribute ("TxPowerLevels", UintegerValue (1));
3521
3522 phySta1->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerStart));
3523 phySta1->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerEnd));
3524 phySta1->SetAttribute ("TxPowerLevels", UintegerValue (m_txPowerLevels));
3525
3526 phySta2->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerStart));
3527 phySta2->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerEnd));
3528 phySta2->SetAttribute ("TxPowerLevels", UintegerValue (m_txPowerLevels));
3529
3530 Time relativeStart = MilliSeconds (0);
3531 if (setupBa)
3532 {
3533 //Set up BA for each station once the association phase has ended
3534 //so that a BA session is established when the MU-BAR is received.
3535 Simulator::Schedule (MilliSeconds (800), &TestUlOfdmaPowerControl::SetupBa, this, m_sta1Dev->GetAddress ());
3536 Simulator::Schedule (MilliSeconds (850), &TestUlOfdmaPowerControl::SetupBa, this, m_sta2Dev->GetAddress ());
3537 relativeStart = MilliSeconds (1000);
3538 }
3539 else
3540 {
3541 Ptr<ApWifiMac> apMac = DynamicCast<ApWifiMac> (m_apDev->GetMac ());
3542 NS_ASSERT (apMac);
3543 apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
3544 }
3545
3546 Simulator::Schedule (relativeStart, &TestUlOfdmaPowerControl::ReplaceReceiveOkCallbackOfAp, this);
3547
3548 {
3549 //Verify that the RSSI from STA 1 is consistent with what was requested
3550 std::vector<uint16_t> staIds {1};
3551 Simulator::Schedule (relativeStart, &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3552 }
3553
3554 {
3555 //Verify that the RSSI from STA 2 is consistent with what was requested
3556 std::vector<uint16_t> staIds {2};
3557 Simulator::Schedule (relativeStart + MilliSeconds (20), &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3558 }
3559
3560 {
3561 //Verify that the RSSI from STA 1 and 2 is consistent with what was requested
3562 std::vector<uint16_t> staIds {1, 2};
3563 Simulator::Schedule (relativeStart + MilliSeconds (40), &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3564 }
3565
3566 Simulator::Stop (relativeStart + MilliSeconds (100));
3567 Simulator::Run ();
3568 }
3569
3570 void
DoRun(void)3571 TestUlOfdmaPowerControl::DoRun (void)
3572 {
3573 //Power configurations
3574 m_txPowerAp = 20; //dBm, so as to have -30 and -36 dBm at STA 1 and STA 2 resp.,
3575 //since path loss = 50 dB for AP <-> STA 1 and 56 dB for AP <-> STA 2
3576 m_txPowerStart = 15; //dBm
3577
3578 //Requested UL RSSIs: should correspond to 20 dBm transmit power at STAs
3579 m_requestedRssiSta1 = -30.0;
3580 m_requestedRssiSta2 = -36.0;
3581
3582 //Test single power level
3583 {
3584 //STA power configurations: 15 dBm only
3585 m_txPowerEnd = 15;
3586 m_txPowerLevels = 1;
3587
3588 //Expected UL RSSIs, considering that the provided power is 5 dB less than requested,
3589 //regardless of the estimated path loss.
3590 m_rssiSta1 = -35.0; // 15 dBm - 50 dB
3591 m_rssiSta2 = -41.0; // 15 dBm - 56 dB
3592
3593 RunOne (true);
3594 }
3595
3596 //Test 2 dBm granularity
3597 {
3598 //STA power configurations: [15:2:25] dBm
3599 m_txPowerEnd = 25;
3600 m_txPowerLevels = 6;
3601
3602 //Expected UL RSSIs, considering that the provided power (21 dBm) is 1 dB more than requested
3603 m_rssiSta1 = -29.0; // 21 dBm - 50 dB
3604 m_rssiSta2 = -35.0; // 21 dBm - 50 dB
3605
3606 RunOne (false);
3607 }
3608
3609 //Test 1 dBm granularity
3610 {
3611 //STA power configurations: [15:1:25] dBm
3612 m_txPowerEnd = 25;
3613 m_txPowerLevels = 11;
3614
3615 //Expected UL RSSIs, considering that we can correctly tune the transmit power
3616 m_rssiSta1 = -30.0; // 20 dBm - 50 dB
3617 m_rssiSta2 = -36.0; // 20 dBm - 56 dB
3618
3619 RunOne (false);
3620 }
3621
3622 //Ask for different power levels (3 dB difference between HE_TB_PPDUs)
3623 {
3624 //STA power configurations: [15:1:25] dBm
3625 m_txPowerEnd = 25;
3626 m_txPowerLevels = 11;
3627
3628 //Requested UL RSSIs
3629 m_requestedRssiSta1 = -28.0; //2 dB higher than previously -> Tx power = 22 dBm at STA 1
3630 m_requestedRssiSta2 = -37.0; //1 dB less than previously -> Tx power = 19 dBm at STA 2
3631
3632 //Expected UL RSSIs, considering that we can correctly tune the transmit power
3633 m_rssiSta1 = -28.0; // 22 dBm - 50 dB
3634 m_rssiSta2 = -37.0; // 19 dBm - 56 dB
3635
3636 RunOne (false);
3637 }
3638
3639 Simulator::Destroy ();
3640 }
3641
3642
3643 /**
3644 * \ingroup wifi-test
3645 * \ingroup tests
3646 *
3647 * \brief wifi PHY OFDMA Test Suite
3648 */
3649 class WifiPhyOfdmaTestSuite : public TestSuite
3650 {
3651 public:
3652 WifiPhyOfdmaTestSuite ();
3653 };
3654
WifiPhyOfdmaTestSuite()3655 WifiPhyOfdmaTestSuite::WifiPhyOfdmaTestSuite ()
3656 : TestSuite ("wifi-phy-ofdma", UNIT)
3657 {
3658 AddTestCase (new TestDlOfdmaPhyTransmission, TestCase::QUICK);
3659 AddTestCase (new TestUlOfdmaPpduUid, TestCase::QUICK);
3660 AddTestCase (new TestMultipleHeTbPreambles, TestCase::QUICK);
3661 AddTestCase (new TestUlOfdmaPhyTransmission, TestCase::QUICK);
3662 AddTestCase (new TestPhyPaddingExclusion, TestCase::QUICK);
3663 AddTestCase (new TestUlOfdmaPowerControl, TestCase::QUICK);
3664 }
3665
3666 static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite; ///< the test suite
3667