A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Documentation ▼
Installation
Manual
Models
Contributing
Wiki
Development ▼
API Docs
Issue Tracker
Merge Requests
API
Loading...
Searching...
No Matches
wifi-phy-ofdma-test.cc
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2019 University of Washington
3
*
4
* SPDX-License-Identifier: GPL-2.0-only
5
*
6
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7
*/
8
9
#include "ns3/ap-wifi-mac.h"
10
#include "ns3/boolean.h"
11
#include "ns3/constant-position-mobility-model.h"
12
#include "ns3/ctrl-headers.h"
13
#include "ns3/double.h"
14
#include "ns3/he-configuration.h"
15
#include "ns3/he-phy.h"
16
#include "ns3/he-ppdu.h"
17
#include "ns3/interference-helper.h"
18
#include "ns3/log.h"
19
#include "ns3/mobility-helper.h"
20
#include "ns3/multi-model-spectrum-channel.h"
21
#include "ns3/nist-error-rate-model.h"
22
#include "ns3/node.h"
23
#include "ns3/non-communicating-net-device.h"
24
#include "ns3/pointer.h"
25
#include "ns3/rng-seed-manager.h"
26
#include "ns3/simulator.h"
27
#include "ns3/spectrum-wifi-helper.h"
28
#include "ns3/spectrum-wifi-phy.h"
29
#include "ns3/sta-wifi-mac.h"
30
#include "ns3/string.h"
31
#include "ns3/test.h"
32
#include "ns3/threshold-preamble-detection-model.h"
33
#include "ns3/txop.h"
34
#include "ns3/waveform-generator.h"
35
#include "ns3/wifi-mac-header.h"
36
#include "ns3/wifi-net-device.h"
37
#include "ns3/wifi-phy-listener.h"
38
#include "ns3/wifi-psdu.h"
39
#include "ns3/wifi-spectrum-phy-interface.h"
40
#include "ns3/wifi-spectrum-signal-parameters.h"
41
#include "ns3/wifi-spectrum-value-helper.h"
42
#include "ns3/wifi-utils.h"
43
44
#include <algorithm>
45
#include <iterator>
46
#include <memory>
47
48
using namespace
ns3
;
49
50
NS_LOG_COMPONENT_DEFINE
(
"WifiPhyOfdmaTest"
);
51
52
static
const
uint8_t
DEFAULT_CHANNEL_NUMBER
= 36;
53
static
const
MHz_u
DEFAULT_FREQUENCY
{5180};
54
static
const
WifiPhyBand
DEFAULT_WIFI_BAND
=
WIFI_PHY_BAND_5GHZ
;
55
static
const
MHz_u
DEFAULT_CHANNEL_WIDTH
{20};
56
static
const
MHz_u
DEFAULT_GUARD_WIDTH
=
57
DEFAULT_CHANNEL_WIDTH
;
// expanded to channel width to model spectrum mask
58
59
/**
60
* HE PHY slightly modified so as to return a given
61
* STA-ID in case of DL MU for OfdmaSpectrumWifiPhy.
62
*/
63
class
OfdmaTestHePhy
:
public
HePhy
64
{
65
public
:
66
/**
67
* Constructor
68
*
69
* @param staId the ID of the STA to which this PHY belongs to
70
*/
71
OfdmaTestHePhy
(uint16_t staId);
72
~OfdmaTestHePhy
()
override
;
73
74
/**
75
* Return the STA ID that has been assigned to the station this PHY belongs to.
76
* This is typically called for MU PPDUs, in order to pick the correct PSDU.
77
*
78
* @param ppdu the PPDU for which the STA ID is requested
79
* @return the STA ID
80
*/
81
uint16_t
GetStaId
(
const
Ptr<const WifiPpdu>
ppdu)
const override
;
82
83
/**
84
* Set the global PPDU UID counter.
85
*
86
* @param uid the value to which the global PPDU UID counter should be set
87
*/
88
void
SetGlobalPpduUid
(uint64_t uid);
89
90
private
:
91
uint16_t
m_staId
;
///< ID of the STA to which this PHY belongs to
92
};
// class OfdmaTestHePhy
93
94
OfdmaTestHePhy::OfdmaTestHePhy
(uint16_t staId)
95
:
HePhy
(),
96
m_staId(staId)
97
{
98
}
99
100
OfdmaTestHePhy::~OfdmaTestHePhy
()
101
{
102
}
103
104
uint16_t
105
OfdmaTestHePhy::GetStaId
(
const
Ptr<const WifiPpdu>
ppdu)
const
106
{
107
if
(ppdu->GetType() ==
WIFI_PPDU_TYPE_DL_MU
)
108
{
109
return
m_staId
;
110
}
111
return
HePhy::GetStaId
(ppdu);
112
}
113
114
void
115
OfdmaTestHePhy::SetGlobalPpduUid
(uint64_t uid)
116
{
117
m_globalPpduUid
= uid;
118
}
119
120
/**
121
* SpectrumWifiPhy used for testing OFDMA.
122
*/
123
class
OfdmaSpectrumWifiPhy
:
public
SpectrumWifiPhy
124
{
125
public
:
126
/**
127
* @brief Get the type ID.
128
* @return the object TypeId
129
*/
130
static
TypeId
GetTypeId
();
131
/**
132
* Constructor
133
*
134
* @param staId the ID of the STA to which this PHY belongs to
135
*/
136
OfdmaSpectrumWifiPhy
(uint16_t staId);
137
~OfdmaSpectrumWifiPhy
()
override
;
138
139
void
DoInitialize
()
override
;
140
void
DoDispose
()
override
;
141
142
using
WifiPhy::Reset
;
143
void
StartTx
(
Ptr<const WifiPpdu>
ppdu)
override
;
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
* Set the global PPDU UID counter.
154
*
155
* @param uid the value to which the global PPDU UID counter should be set
156
*/
157
void
SetPpduUid
(uint64_t uid);
158
159
/**
160
* Since we assume trigger frame was previously received from AP, this is used to set its UID
161
*
162
* @param uid the PPDU UID of the trigger frame
163
*/
164
void
SetTriggerFrameUid
(uint64_t uid);
165
166
/**
167
* @return the current preamble events map
168
*/
169
std::map<std::pair<uint64_t, WifiPreamble>,
Ptr<Event>
>&
GetCurrentPreambleEvents
();
170
/**
171
* @return the current event
172
*/
173
Ptr<Event>
GetCurrentEvent
();
174
175
/**
176
* Wrapper to InterferenceHelper method.
177
*
178
* @param energy the minimum energy requested
179
* @param band identify the requested band
180
*
181
* @returns the expected amount of time the observed
182
* energy on the medium for a given band will
183
* be higher than the requested threshold.
184
*/
185
Time
GetEnergyDuration
(
Watt_u
energy,
WifiSpectrumBandInfo
band);
186
187
/**
188
* @return a const pointer to the HE PHY instance
189
*/
190
Ptr<const HePhy>
GetHePhy
()
const
;
191
192
private
:
193
Ptr<OfdmaTestHePhy>
m_ofdmTestHePhy
;
///< Pointer to HE PHY instance used for OFDMA test
194
TracedCallback<uint64_t>
195
m_phyTxPpduUidTrace
;
//!< Callback providing UID of the PPDU that is about to be transmitted
196
};
// class OfdmaSpectrumWifiPhy
197
198
TypeId
199
OfdmaSpectrumWifiPhy::GetTypeId
()
200
{
201
static
TypeId
tid =
202
TypeId
(
"ns3::OfdmaSpectrumWifiPhy"
)
203
.
SetParent
<
SpectrumWifiPhy
>()
204
.SetGroupName(
"Wifi"
)
205
.AddTraceSource(
"TxPpduUid"
,
206
"UID of the PPDU to be transmitted"
,
207
MakeTraceSourceAccessor
(&
OfdmaSpectrumWifiPhy::m_phyTxPpduUidTrace
),
208
"ns3::OfdmaSpectrumWifiPhy::TxPpduUidCallback"
);
209
return
tid;
210
}
211
212
OfdmaSpectrumWifiPhy::OfdmaSpectrumWifiPhy
(uint16_t staId)
213
:
SpectrumWifiPhy
()
214
{
215
m_ofdmTestHePhy
=
Create<OfdmaTestHePhy>
(staId);
216
m_ofdmTestHePhy
->
SetOwner
(
this
);
217
}
218
219
OfdmaSpectrumWifiPhy::~OfdmaSpectrumWifiPhy
()
220
{
221
}
222
223
void
224
OfdmaSpectrumWifiPhy::DoInitialize
()
225
{
226
// Replace HE PHY instance with test instance
227
m_phyEntities
[
WIFI_MOD_CLASS_HE
] =
m_ofdmTestHePhy
;
228
SpectrumWifiPhy::DoInitialize
();
229
}
230
231
void
232
OfdmaSpectrumWifiPhy::DoDispose
()
233
{
234
m_ofdmTestHePhy
=
nullptr
;
235
SpectrumWifiPhy::DoDispose
();
236
}
237
238
void
239
OfdmaSpectrumWifiPhy::SetPpduUid
(uint64_t uid)
240
{
241
m_ofdmTestHePhy
->
SetGlobalPpduUid
(uid);
242
m_previouslyRxPpduUid
= uid;
243
}
244
245
void
246
OfdmaSpectrumWifiPhy::SetTriggerFrameUid
(uint64_t uid)
247
{
248
m_previouslyRxPpduUid
= uid;
249
}
250
251
void
252
OfdmaSpectrumWifiPhy::StartTx
(
Ptr<const WifiPpdu>
ppdu)
253
{
254
m_phyTxPpduUidTrace
(ppdu->GetUid());
255
SpectrumWifiPhy::StartTx
(ppdu);
256
}
257
258
std::map<std::pair<uint64_t, WifiPreamble>,
Ptr<Event>
>&
259
OfdmaSpectrumWifiPhy::GetCurrentPreambleEvents
()
260
{
261
return
m_currentPreambleEvents
;
262
}
263
264
Ptr<Event>
265
OfdmaSpectrumWifiPhy::GetCurrentEvent
()
266
{
267
return
m_currentEvent
;
268
}
269
270
Time
271
OfdmaSpectrumWifiPhy::GetEnergyDuration
(
Watt_u
energy,
WifiSpectrumBandInfo
band)
272
{
273
return
m_interference
->GetEnergyDuration(energy, band);
274
}
275
276
Ptr<const HePhy>
277
OfdmaSpectrumWifiPhy::GetHePhy
()
const
278
{
279
return
DynamicCast<const HePhy>
(
GetLatestPhyEntity
());
280
}
281
282
/**
283
* @ingroup wifi-test
284
* @ingroup tests
285
*
286
* @brief DL-OFDMA PHY test
287
*/
288
class
TestDlOfdmaPhyTransmission
:
public
TestCase
289
{
290
public
:
291
TestDlOfdmaPhyTransmission
();
292
~TestDlOfdmaPhyTransmission
()
override
;
293
294
private
:
295
void
DoSetup
()
override
;
296
void
DoTeardown
()
override
;
297
void
DoRun
()
override
;
298
299
/**
300
* Receive success function for STA 1
301
* @param psdu the PSDU
302
* @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
303
* @param txVector the transmit vector
304
* @param statusPerMpdu reception status per MPDU
305
*/
306
void
RxSuccessSta1
(
Ptr<const WifiPsdu>
psdu,
307
RxSignalInfo
rxSignalInfo,
308
const
WifiTxVector
& txVector,
309
const
std::vector<bool>& statusPerMpdu);
310
/**
311
* Receive success function for STA 2
312
* @param psdu the PSDU
313
* @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
314
* @param txVector the transmit vector
315
* @param statusPerMpdu reception status per MPDU
316
*/
317
void
RxSuccessSta2
(
Ptr<const WifiPsdu>
psdu,
318
RxSignalInfo
rxSignalInfo,
319
const
WifiTxVector
& txVector,
320
const
std::vector<bool>& statusPerMpdu);
321
/**
322
* Receive success function for STA 3
323
* @param psdu the PSDU
324
* @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
325
* @param txVector the transmit vector
326
* @param statusPerMpdu reception status per MPDU
327
*/
328
void
RxSuccessSta3
(
Ptr<const WifiPsdu>
psdu,
329
RxSignalInfo
rxSignalInfo,
330
const
WifiTxVector
& txVector,
331
const
std::vector<bool>& statusPerMpdu);
332
333
/**
334
* Receive failure function for STA 1
335
* @param psdu the PSDU
336
*/
337
void
RxFailureSta1
(
Ptr<const WifiPsdu>
psdu);
338
/**
339
* Receive failure function for STA 2
340
* @param psdu the PSDU
341
*/
342
void
RxFailureSta2
(
Ptr<const WifiPsdu>
psdu);
343
/**
344
* Receive failure function for STA 3
345
* @param psdu the PSDU
346
*/
347
void
RxFailureSta3
(
Ptr<const WifiPsdu>
psdu);
348
349
/**
350
* Check the results for STA 1
351
* @param expectedRxSuccess the expected number of RX success
352
* @param expectedRxFailure the expected number of RX failures
353
* @param expectedRxBytes the expected number of RX bytes
354
*/
355
void
CheckResultsSta1
(
uint32_t
expectedRxSuccess,
356
uint32_t
expectedRxFailure,
357
uint32_t
expectedRxBytes);
358
/**
359
* Check the results for STA 2
360
* @param expectedRxSuccess the expected number of RX success
361
* @param expectedRxFailure the expected number of RX failures
362
* @param expectedRxBytes the expected number of RX bytes
363
*/
364
void
CheckResultsSta2
(
uint32_t
expectedRxSuccess,
365
uint32_t
expectedRxFailure,
366
uint32_t
expectedRxBytes);
367
/**
368
* Check the results for STA 3
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
CheckResultsSta3
(
uint32_t
expectedRxSuccess,
374
uint32_t
expectedRxFailure,
375
uint32_t
expectedRxBytes);
376
377
/**
378
* Reset the results
379
*/
380
void
ResetResults
();
381
382
/**
383
* Send MU-PPDU function
384
* @param rxStaId1 the ID of the recipient STA for the first PSDU
385
* @param rxStaId2 the ID of the recipient STA for the second PSDU
386
*/
387
void
SendMuPpdu
(uint16_t rxStaId1, uint16_t rxStaId2);
388
389
/**
390
* Generate interference function
391
* @param interferencePsd the PSD of the interference to be generated
392
* @param duration the duration of the interference
393
*/
394
void
GenerateInterference
(
Ptr<SpectrumValue>
interferencePsd,
Time
duration);
395
/**
396
* Stop interference function
397
*/
398
void
StopInterference
();
399
400
/**
401
* Run one function
402
*/
403
void
RunOne
();
404
405
/**
406
* Schedule now to check the PHY state
407
* @param phy the PHY
408
* @param expectedState the expected state of the PHY
409
*/
410
void
CheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState);
411
/**
412
* Check the PHY state now
413
* @param phy the PHY
414
* @param expectedState the expected state of the PHY
415
*/
416
void
DoCheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState);
417
418
uint32_t
m_countRxSuccessSta1
;
///< count RX success for STA 1
419
uint32_t
m_countRxSuccessSta2
;
///< count RX success for STA 2
420
uint32_t
m_countRxSuccessSta3
;
///< count RX success for STA 3
421
uint32_t
m_countRxFailureSta1
;
///< count RX failure for STA 1
422
uint32_t
m_countRxFailureSta2
;
///< count RX failure for STA 2
423
uint32_t
m_countRxFailureSta3
;
///< count RX failure for STA 3
424
uint32_t
m_countRxBytesSta1
;
///< count RX bytes for STA 1
425
uint32_t
m_countRxBytesSta2
;
///< count RX bytes for STA 2
426
uint32_t
m_countRxBytesSta3
;
///< count RX bytes for STA 3
427
428
Ptr<SpectrumWifiPhy>
m_phyAp
;
///< PHY of AP
429
Ptr<OfdmaSpectrumWifiPhy>
m_phySta1
;
///< PHY of STA 1
430
Ptr<OfdmaSpectrumWifiPhy>
m_phySta2
;
///< PHY of STA 2
431
Ptr<OfdmaSpectrumWifiPhy>
m_phySta3
;
///< PHY of STA 3
432
Ptr<WaveformGenerator>
m_phyInterferer
;
///< PHY of interferer
433
434
MHz_u
m_frequency
;
///< frequency
435
MHz_u
m_channelWidth
;
///< channel width
436
Time
m_expectedPpduDuration
;
///< expected duration to send MU PPDU
437
};
438
439
TestDlOfdmaPhyTransmission::TestDlOfdmaPhyTransmission
()
440
:
TestCase
(
"DL-OFDMA PHY test"
),
441
m_countRxSuccessSta1(0),
442
m_countRxSuccessSta2(0),
443
m_countRxSuccessSta3(0),
444
m_countRxFailureSta1(0),
445
m_countRxFailureSta2(0),
446
m_countRxFailureSta3(0),
447
m_countRxBytesSta1(0),
448
m_countRxBytesSta2(0),
449
m_countRxBytesSta3(0),
450
m_frequency(
DEFAULT_FREQUENCY
),
451
m_channelWidth(
DEFAULT_CHANNEL_WIDTH
),
452
m_expectedPpduDuration(
NanoSeconds
(306400))
453
{
454
}
455
456
void
457
TestDlOfdmaPhyTransmission::ResetResults
()
458
{
459
m_countRxSuccessSta1
= 0;
460
m_countRxSuccessSta2
= 0;
461
m_countRxSuccessSta3
= 0;
462
m_countRxFailureSta1
= 0;
463
m_countRxFailureSta2
= 0;
464
m_countRxFailureSta3
= 0;
465
m_countRxBytesSta1
= 0;
466
m_countRxBytesSta2
= 0;
467
m_countRxBytesSta3
= 0;
468
}
469
470
void
471
TestDlOfdmaPhyTransmission::SendMuPpdu
(uint16_t rxStaId1, uint16_t rxStaId2)
472
{
473
NS_LOG_FUNCTION
(
this
<< rxStaId1 << rxStaId2);
474
WifiConstPsduMap
psdus;
475
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
476
0,
477
WIFI_PREAMBLE_HE_MU
,
478
NanoSeconds
(800),
479
1,
480
1,
481
0,
482
m_channelWidth
,
483
false
,
484
false
};
485
HeRu::RuType
ruType =
HeRu::RU_106_TONE
;
486
if
(
m_channelWidth
==
MHz_u
{20})
487
{
488
ruType =
HeRu::RU_106_TONE
;
489
txVector.SetRuAllocation({96}, 0);
490
}
491
else
if
(
m_channelWidth
==
MHz_u
{40})
492
{
493
ruType =
HeRu::RU_242_TONE
;
494
txVector.SetRuAllocation({192, 192}, 0);
495
}
496
else
if
(
m_channelWidth
==
MHz_u
{80})
497
{
498
ruType =
HeRu::RU_484_TONE
;
499
txVector.SetRuAllocation({200, 200, 200, 200}, 0);
500
}
501
else
if
(
m_channelWidth
==
MHz_u
{160})
502
{
503
ruType =
HeRu::RU_996_TONE
;
504
txVector.SetRuAllocation({208, 208, 208, 208, 208, 208, 208, 208}, 0);
505
}
506
else
507
{
508
NS_ASSERT_MSG
(
false
,
"Unsupported channel width"
);
509
}
510
511
txVector.SetSigBMode(
VhtPhy::GetVhtMcs5
());
512
513
HeRu::RuSpec
ru1(ruType, 1,
true
);
514
txVector.SetRu(ru1, rxStaId1);
515
txVector.SetMode(
HePhy::GetHeMcs7
(), rxStaId1);
516
txVector.SetNss(1, rxStaId1);
517
518
HeRu::RuSpec
ru2(ruType, (
m_channelWidth
==
MHz_u
{160} ? 1 : 2),
m_channelWidth
!=
MHz_u
{160});
519
txVector.SetRu(ru2, rxStaId2);
520
txVector.SetMode(
HePhy::GetHeMcs9
(), rxStaId2);
521
txVector.SetNss(1, rxStaId2);
522
523
Ptr<Packet>
pkt1 =
Create<Packet>
(1000);
524
WifiMacHeader
hdr1;
525
hdr1.
SetType
(
WIFI_MAC_QOSDATA
);
526
hdr1.
SetQosTid
(0);
527
hdr1.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:01"
));
528
hdr1.
SetSequenceNumber
(1);
529
Ptr<WifiPsdu>
psdu1 =
Create<WifiPsdu>
(pkt1, hdr1);
530
psdus.insert(std::make_pair(rxStaId1, psdu1));
531
532
Ptr<Packet>
pkt2 =
Create<Packet>
(1500);
533
WifiMacHeader
hdr2;
534
hdr2.
SetType
(
WIFI_MAC_QOSDATA
);
535
hdr2.
SetQosTid
(0);
536
hdr2.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:02"
));
537
hdr2.
SetSequenceNumber
(2);
538
Ptr<WifiPsdu>
psdu2 =
Create<WifiPsdu>
(pkt2, hdr2);
539
psdus.insert(std::make_pair(rxStaId2, psdu2));
540
541
m_phyAp
->Send(psdus, txVector);
542
}
543
544
void
545
TestDlOfdmaPhyTransmission::GenerateInterference
(
Ptr<SpectrumValue>
interferencePsd,
Time
duration)
546
{
547
m_phyInterferer
->SetTxPowerSpectralDensity(interferencePsd);
548
m_phyInterferer
->SetPeriod(duration);
549
m_phyInterferer
->Start();
550
Simulator::Schedule
(duration, &
TestDlOfdmaPhyTransmission::StopInterference
,
this
);
551
}
552
553
void
554
TestDlOfdmaPhyTransmission::StopInterference
()
555
{
556
m_phyInterferer
->Stop();
557
}
558
559
TestDlOfdmaPhyTransmission::~TestDlOfdmaPhyTransmission
()
560
{
561
}
562
563
void
564
TestDlOfdmaPhyTransmission::RxSuccessSta1
(
Ptr<const WifiPsdu>
psdu,
565
RxSignalInfo
rxSignalInfo,
566
const
WifiTxVector
& txVector,
567
const
std::vector<bool>&
/*statusPerMpdu*/
)
568
{
569
NS_LOG_FUNCTION
(
this
<< *psdu << rxSignalInfo << txVector);
570
m_countRxSuccessSta1
++;
571
m_countRxBytesSta1
+= (psdu->GetSize() - 30);
572
}
573
574
void
575
TestDlOfdmaPhyTransmission::RxSuccessSta2
(
Ptr<const WifiPsdu>
psdu,
576
RxSignalInfo
rxSignalInfo,
577
const
WifiTxVector
& txVector,
578
const
std::vector<bool>&
/*statusPerMpdu*/
)
579
{
580
NS_LOG_FUNCTION
(
this
<< *psdu << rxSignalInfo << txVector);
581
m_countRxSuccessSta2
++;
582
m_countRxBytesSta2
+= (psdu->GetSize() - 30);
583
}
584
585
void
586
TestDlOfdmaPhyTransmission::RxSuccessSta3
(
Ptr<const WifiPsdu>
psdu,
587
RxSignalInfo
rxSignalInfo,
588
const
WifiTxVector
& txVector,
589
const
std::vector<bool>&
/*statusPerMpdu*/
)
590
{
591
NS_LOG_FUNCTION
(
this
<< *psdu << rxSignalInfo << txVector);
592
m_countRxSuccessSta3
++;
593
m_countRxBytesSta3
+= (psdu->GetSize() - 30);
594
}
595
596
void
597
TestDlOfdmaPhyTransmission::RxFailureSta1
(
Ptr<const WifiPsdu>
psdu)
598
{
599
NS_LOG_FUNCTION
(
this
<< *psdu);
600
m_countRxFailureSta1
++;
601
}
602
603
void
604
TestDlOfdmaPhyTransmission::RxFailureSta2
(
Ptr<const WifiPsdu>
psdu)
605
{
606
NS_LOG_FUNCTION
(
this
<< *psdu);
607
m_countRxFailureSta2
++;
608
}
609
610
void
611
TestDlOfdmaPhyTransmission::RxFailureSta3
(
Ptr<const WifiPsdu>
psdu)
612
{
613
NS_LOG_FUNCTION
(
this
<< *psdu);
614
m_countRxFailureSta3
++;
615
}
616
617
void
618
TestDlOfdmaPhyTransmission::CheckResultsSta1
(
uint32_t
expectedRxSuccess,
619
uint32_t
expectedRxFailure,
620
uint32_t
expectedRxBytes)
621
{
622
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessSta1
,
623
expectedRxSuccess,
624
"The number of successfully received packets by STA 1 is not correct!"
);
625
NS_TEST_ASSERT_MSG_EQ
(
m_countRxFailureSta1
,
626
expectedRxFailure,
627
"The number of unsuccessfuly received packets by STA 1 is not correct!"
);
628
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesSta1
,
629
expectedRxBytes,
630
"The number of bytes received by STA 1 is not correct!"
);
631
}
632
633
void
634
TestDlOfdmaPhyTransmission::CheckResultsSta2
(
uint32_t
expectedRxSuccess,
635
uint32_t
expectedRxFailure,
636
uint32_t
expectedRxBytes)
637
{
638
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessSta2
,
639
expectedRxSuccess,
640
"The number of successfully received packets by STA 2 is not correct!"
);
641
NS_TEST_ASSERT_MSG_EQ
(
m_countRxFailureSta2
,
642
expectedRxFailure,
643
"The number of unsuccessfuly received packets by STA 2 is not correct!"
);
644
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesSta2
,
645
expectedRxBytes,
646
"The number of bytes received by STA 2 is not correct!"
);
647
}
648
649
void
650
TestDlOfdmaPhyTransmission::CheckResultsSta3
(
uint32_t
expectedRxSuccess,
651
uint32_t
expectedRxFailure,
652
uint32_t
expectedRxBytes)
653
{
654
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessSta3
,
655
expectedRxSuccess,
656
"The number of successfully received packets by STA 3 is not correct!"
);
657
NS_TEST_ASSERT_MSG_EQ
(
m_countRxFailureSta3
,
658
expectedRxFailure,
659
"The number of unsuccessfuly received packets by STA 3 is not correct!"
);
660
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesSta3
,
661
expectedRxBytes,
662
"The number of bytes received by STA 3 is not correct!"
);
663
}
664
665
void
666
TestDlOfdmaPhyTransmission::CheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState)
667
{
668
// This is needed to make sure PHY state will be checked as the last event if a state change
669
// occurred at the exact same time as the check
670
Simulator::ScheduleNow
(&
TestDlOfdmaPhyTransmission::DoCheckPhyState
,
this
, phy, expectedState);
671
}
672
673
void
674
TestDlOfdmaPhyTransmission::DoCheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
675
WifiPhyState
expectedState)
676
{
677
WifiPhyState
currentState;
678
PointerValue
ptr;
679
phy->GetAttribute(
"State"
, ptr);
680
Ptr<WifiPhyStateHelper>
state =
DynamicCast<WifiPhyStateHelper>
(ptr.
Get
<
WifiPhyStateHelper
>());
681
currentState = state->GetState();
682
NS_LOG_FUNCTION
(
this
<< currentState);
683
NS_TEST_ASSERT_MSG_EQ
(currentState,
684
expectedState,
685
"PHY State "
<< currentState <<
" does not match expected state "
686
<< expectedState <<
" at "
<<
Simulator::Now
());
687
}
688
689
void
690
TestDlOfdmaPhyTransmission::DoSetup
()
691
{
692
Ptr<MultiModelSpectrumChannel>
spectrumChannel =
CreateObject<MultiModelSpectrumChannel>
();
693
Ptr<FriisPropagationLossModel>
lossModel =
CreateObject<FriisPropagationLossModel>
();
694
lossModel->SetFrequency(
MHzToHz
(
m_frequency
));
695
spectrumChannel->AddPropagationLossModel(lossModel);
696
Ptr<ConstantSpeedPropagationDelayModel>
delayModel =
697
CreateObject<ConstantSpeedPropagationDelayModel>
();
698
spectrumChannel->SetPropagationDelayModel(delayModel);
699
700
Ptr<Node>
apNode =
CreateObject<Node>
();
701
Ptr<WifiNetDevice>
apDev =
CreateObject<WifiNetDevice>
();
702
m_phyAp
=
CreateObject<SpectrumWifiPhy>
();
703
Ptr<InterferenceHelper>
apInterferenceHelper =
CreateObject<InterferenceHelper>
();
704
m_phyAp
->SetInterferenceHelper(apInterferenceHelper);
705
Ptr<ErrorRateModel>
apErrorModel =
CreateObject<NistErrorRateModel>
();
706
m_phyAp
->SetErrorRateModel(apErrorModel);
707
m_phyAp
->SetDevice(apDev);
708
m_phyAp
->AddChannel(spectrumChannel);
709
m_phyAp
->ConfigureStandard(
WIFI_STANDARD_80211ax
);
710
Ptr<ConstantPositionMobilityModel>
apMobility =
CreateObject<ConstantPositionMobilityModel>
();
711
m_phyAp
->SetMobility(apMobility);
712
apDev->SetPhy(
m_phyAp
);
713
apNode->AggregateObject(apMobility);
714
apNode->AddDevice(apDev);
715
716
Ptr<Node>
sta1Node =
CreateObject<Node>
();
717
Ptr<WifiNetDevice>
sta1Dev =
CreateObject<WifiNetDevice>
();
718
m_phySta1
=
CreateObject<OfdmaSpectrumWifiPhy>
(1);
719
Ptr<InterferenceHelper>
sta1InterferenceHelper =
CreateObject<InterferenceHelper>
();
720
m_phySta1
->
SetInterferenceHelper
(sta1InterferenceHelper);
721
Ptr<ErrorRateModel>
sta1ErrorModel =
CreateObject<NistErrorRateModel>
();
722
m_phySta1
->
SetErrorRateModel
(sta1ErrorModel);
723
m_phySta1
->
SetDevice
(sta1Dev);
724
m_phySta1
->
AddChannel
(spectrumChannel);
725
m_phySta1
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
726
m_phySta1
->
SetReceiveOkCallback
(
MakeCallback
(&
TestDlOfdmaPhyTransmission::RxSuccessSta1
,
this
));
727
m_phySta1
->
SetReceiveErrorCallback
(
728
MakeCallback
(&
TestDlOfdmaPhyTransmission::RxFailureSta1
,
this
));
729
Ptr<ConstantPositionMobilityModel>
sta1Mobility =
CreateObject<ConstantPositionMobilityModel>
();
730
m_phySta1
->
SetMobility
(sta1Mobility);
731
sta1Dev->SetPhy(
m_phySta1
);
732
sta1Node->AggregateObject(sta1Mobility);
733
sta1Node->AddDevice(sta1Dev);
734
735
Ptr<Node>
sta2Node =
CreateObject<Node>
();
736
Ptr<WifiNetDevice>
sta2Dev =
CreateObject<WifiNetDevice>
();
737
m_phySta2
=
CreateObject<OfdmaSpectrumWifiPhy>
(2);
738
Ptr<InterferenceHelper>
sta2InterferenceHelper =
CreateObject<InterferenceHelper>
();
739
m_phySta2
->
SetInterferenceHelper
(sta2InterferenceHelper);
740
Ptr<ErrorRateModel>
sta2ErrorModel =
CreateObject<NistErrorRateModel>
();
741
m_phySta2
->
SetErrorRateModel
(sta2ErrorModel);
742
m_phySta2
->
SetDevice
(sta2Dev);
743
m_phySta2
->
AddChannel
(spectrumChannel);
744
m_phySta2
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
745
m_phySta2
->
SetReceiveOkCallback
(
MakeCallback
(&
TestDlOfdmaPhyTransmission::RxSuccessSta2
,
this
));
746
m_phySta2
->
SetReceiveErrorCallback
(
747
MakeCallback
(&
TestDlOfdmaPhyTransmission::RxFailureSta2
,
this
));
748
Ptr<ConstantPositionMobilityModel>
sta2Mobility =
CreateObject<ConstantPositionMobilityModel>
();
749
m_phySta2
->
SetMobility
(sta2Mobility);
750
sta2Dev->SetPhy(
m_phySta2
);
751
sta2Node->AggregateObject(sta2Mobility);
752
sta2Node->AddDevice(sta2Dev);
753
754
Ptr<Node>
sta3Node =
CreateObject<Node>
();
755
Ptr<WifiNetDevice>
sta3Dev =
CreateObject<WifiNetDevice>
();
756
m_phySta3
=
CreateObject<OfdmaSpectrumWifiPhy>
(3);
757
Ptr<InterferenceHelper>
sta3InterferenceHelper =
CreateObject<InterferenceHelper>
();
758
m_phySta3
->
SetInterferenceHelper
(sta3InterferenceHelper);
759
Ptr<ErrorRateModel>
sta3ErrorModel =
CreateObject<NistErrorRateModel>
();
760
m_phySta3
->
SetErrorRateModel
(sta3ErrorModel);
761
m_phySta3
->
SetDevice
(sta3Dev);
762
m_phySta3
->
AddChannel
(spectrumChannel);
763
m_phySta3
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
764
m_phySta3
->
SetReceiveOkCallback
(
MakeCallback
(&
TestDlOfdmaPhyTransmission::RxSuccessSta3
,
this
));
765
m_phySta3
->
SetReceiveErrorCallback
(
766
MakeCallback
(&
TestDlOfdmaPhyTransmission::RxFailureSta3
,
this
));
767
Ptr<ConstantPositionMobilityModel>
sta3Mobility =
CreateObject<ConstantPositionMobilityModel>
();
768
m_phySta3
->
SetMobility
(sta3Mobility);
769
sta3Dev->SetPhy(
m_phySta3
);
770
sta3Node->AggregateObject(sta3Mobility);
771
sta3Node->AddDevice(sta3Dev);
772
773
Ptr<Node>
interfererNode =
CreateObject<Node>
();
774
Ptr<NonCommunicatingNetDevice>
interfererDev =
CreateObject<NonCommunicatingNetDevice>
();
775
m_phyInterferer
=
CreateObject<WaveformGenerator>
();
776
m_phyInterferer
->SetDevice(interfererDev);
777
m_phyInterferer
->SetChannel(spectrumChannel);
778
m_phyInterferer
->SetDutyCycle(1);
779
interfererNode->AddDevice(interfererDev);
780
}
781
782
void
783
TestDlOfdmaPhyTransmission::DoTeardown
()
784
{
785
m_phyAp
->Dispose();
786
m_phyAp
=
nullptr
;
787
m_phySta1
->
Dispose
();
788
m_phySta1
=
nullptr
;
789
m_phySta2
->
Dispose
();
790
m_phySta2
=
nullptr
;
791
m_phySta3
->
Dispose
();
792
m_phySta3
=
nullptr
;
793
m_phyInterferer
->
Dispose
();
794
m_phyInterferer
=
nullptr
;
795
}
796
797
void
798
TestDlOfdmaPhyTransmission::RunOne
()
799
{
800
RngSeedManager::SetSeed
(1);
801
RngSeedManager::SetRun
(1);
802
int64_t streamNumber = 0;
803
m_phyAp
->AssignStreams(streamNumber);
804
m_phySta1
->
AssignStreams
(streamNumber);
805
m_phySta2
->
AssignStreams
(streamNumber);
806
m_phySta3
->
AssignStreams
(streamNumber);
807
808
auto
channelNum =
WifiPhyOperatingChannel::FindFirst
(0,
809
m_frequency
,
810
m_channelWidth
,
811
WIFI_STANDARD_80211ax
,
812
WIFI_PHY_BAND_5GHZ
)
813
->number;
814
815
m_phyAp
->SetOperatingChannel(
816
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
817
m_phySta1
->
SetOperatingChannel
(
818
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
819
m_phySta2
->
SetOperatingChannel
(
820
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
821
m_phySta3
->
SetOperatingChannel
(
822
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
823
824
Simulator::Schedule
(
Seconds
(0.5), &
TestDlOfdmaPhyTransmission::ResetResults
,
this
);
825
826
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
827
// Each STA should receive its PSDU.
828
Simulator::Schedule
(
Seconds
(1), &
TestDlOfdmaPhyTransmission::SendMuPpdu
,
this
, 1, 2);
829
830
// Since it takes m_expectedPpduDuration to transmit the PPDU,
831
// all 3 PHYs should be back to IDLE at the same time,
832
// even the PHY that has no PSDU addressed to it.
833
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration
-
NanoSeconds
(1),
834
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
835
this
,
836
m_phySta1
,
837
WifiPhyState::RX);
838
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration
-
NanoSeconds
(1),
839
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
840
this
,
841
m_phySta2
,
842
WifiPhyState::RX);
843
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration
-
NanoSeconds
(1),
844
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
845
this
,
846
m_phySta3
,
847
WifiPhyState::CCA_BUSY);
848
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration
,
849
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
850
this
,
851
m_phySta1
,
852
WifiPhyState::IDLE);
853
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration
,
854
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
855
this
,
856
m_phySta2
,
857
WifiPhyState::IDLE);
858
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration
,
859
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
860
this
,
861
m_phySta3
,
862
WifiPhyState::IDLE);
863
864
// One PSDU of 1000 bytes should have been successfully received by STA 1
865
Simulator::Schedule
(
Seconds
(1.1),
866
&
TestDlOfdmaPhyTransmission::CheckResultsSta1
,
867
this
,
868
1,
869
0,
870
1000);
871
// One PSDU of 1500 bytes should have been successfully received by STA 2
872
Simulator::Schedule
(
Seconds
(1.1),
873
&
TestDlOfdmaPhyTransmission::CheckResultsSta2
,
874
this
,
875
1,
876
0,
877
1500);
878
// No PSDU should have been received by STA 3
879
Simulator::Schedule
(
Seconds
(1.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta3
,
this
, 0, 0, 0);
880
881
Simulator::Schedule
(
Seconds
(1.5), &
TestDlOfdmaPhyTransmission::ResetResults
,
this
);
882
883
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 3:
884
// STA 1 should receive its PSDU, whereas STA 2 should not receive any PSDU
885
// but should keep its PHY busy during all PPDU duration.
886
Simulator::Schedule
(
Seconds
(2), &
TestDlOfdmaPhyTransmission::SendMuPpdu
,
this
, 1, 3);
887
888
// Since it takes m_expectedPpduDuration to transmit the PPDU,
889
// all 3 PHYs should be back to IDLE at the same time,
890
// even the PHY that has no PSDU addressed to it.
891
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration
-
NanoSeconds
(1),
892
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
893
this
,
894
m_phySta1
,
895
WifiPhyState::RX);
896
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration
-
NanoSeconds
(1),
897
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
898
this
,
899
m_phySta2
,
900
WifiPhyState::CCA_BUSY);
901
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration
-
NanoSeconds
(1),
902
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
903
this
,
904
m_phySta3
,
905
WifiPhyState::RX);
906
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration
,
907
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
908
this
,
909
m_phySta1
,
910
WifiPhyState::IDLE);
911
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration
,
912
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
913
this
,
914
m_phySta2
,
915
WifiPhyState::IDLE);
916
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration
,
917
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
918
this
,
919
m_phySta3
,
920
WifiPhyState::IDLE);
921
922
// One PSDU of 1000 bytes should have been successfully received by STA 1
923
Simulator::Schedule
(
Seconds
(2.1),
924
&
TestDlOfdmaPhyTransmission::CheckResultsSta1
,
925
this
,
926
1,
927
0,
928
1000);
929
// No PSDU should have been received by STA 2
930
Simulator::Schedule
(
Seconds
(2.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta2
,
this
, 0, 0, 0);
931
// One PSDU of 1500 bytes should have been successfully received by STA 3
932
Simulator::Schedule
(
Seconds
(2.1),
933
&
TestDlOfdmaPhyTransmission::CheckResultsSta3
,
934
this
,
935
1,
936
0,
937
1500);
938
939
Simulator::Schedule
(
Seconds
(2.5), &
TestDlOfdmaPhyTransmission::ResetResults
,
this
);
940
941
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
942
Simulator::Schedule
(
Seconds
(3), &
TestDlOfdmaPhyTransmission::SendMuPpdu
,
this
, 1, 2);
943
944
// A strong non-wifi interference is generated on RU 1 during PSDU reception
945
BandInfo
bandInfo;
946
bandInfo.
fc
=
MHzToHz
(
m_frequency
- (
m_channelWidth
/ 4));
947
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(
m_channelWidth
/ 4);
948
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(
m_channelWidth
/ 4);
949
Bands
bands;
950
bands.push_back(bandInfo);
951
952
auto
SpectrumInterferenceRu1 =
Create<SpectrumModel>
(bands);
953
auto
interferencePsdRu1 =
Create<SpectrumValue>
(SpectrumInterferenceRu1);
954
Watt_u
interferencePower{0.1};
955
*interferencePsdRu1 = interferencePower / (
MHzToHz
(
m_channelWidth
/ 2) * 20);
956
957
Simulator::Schedule
(
Seconds
(3) +
MicroSeconds
(50),
958
&
TestDlOfdmaPhyTransmission::GenerateInterference
,
959
this
,
960
interferencePsdRu1,
961
MilliSeconds
(100));
962
963
// Since it takes m_expectedPpduDuration to transmit the PPDU,
964
// both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
965
// even the PHY that has no PSDU addressed to it.
966
Simulator::Schedule
(
Seconds
(3) +
m_expectedPpduDuration
-
NanoSeconds
(1),
967
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
968
this
,
969
m_phySta1
,
970
WifiPhyState::RX);
971
Simulator::Schedule
(
Seconds
(3) +
m_expectedPpduDuration
-
NanoSeconds
(1),
972
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
973
this
,
974
m_phySta2
,
975
WifiPhyState::RX);
976
Simulator::Schedule
(
Seconds
(3) +
m_expectedPpduDuration
-
NanoSeconds
(1),
977
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
978
this
,
979
m_phySta3
,
980
WifiPhyState::CCA_BUSY);
981
Simulator::Schedule
(
Seconds
(3) +
m_expectedPpduDuration
,
982
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
983
this
,
984
m_phySta1
,
985
WifiPhyState::CCA_BUSY);
986
Simulator::Schedule
(
Seconds
(3) +
m_expectedPpduDuration
,
987
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
988
this
,
989
m_phySta2
,
990
WifiPhyState::CCA_BUSY);
991
Simulator::Schedule
(
Seconds
(3) +
m_expectedPpduDuration
,
992
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
993
this
,
994
m_phySta3
,
995
WifiPhyState::CCA_BUSY);
996
997
// One PSDU of 1000 bytes should have been unsuccessfuly received by STA 1 (since interference
998
// occupies RU 1)
999
Simulator::Schedule
(
Seconds
(3.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta1
,
this
, 0, 1, 0);
1000
// One PSDU of 1500 bytes should have been successfully received by STA 2
1001
Simulator::Schedule
(
Seconds
(3.1),
1002
&
TestDlOfdmaPhyTransmission::CheckResultsSta2
,
1003
this
,
1004
1,
1005
0,
1006
1500);
1007
// No PSDU should have been received by STA3
1008
Simulator::Schedule
(
Seconds
(3.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta3
,
this
, 0, 0, 0);
1009
1010
Simulator::Schedule
(
Seconds
(3.5), &
TestDlOfdmaPhyTransmission::ResetResults
,
this
);
1011
1012
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
1013
Simulator::Schedule
(
Seconds
(4), &
TestDlOfdmaPhyTransmission::SendMuPpdu
,
this
, 1, 2);
1014
1015
// A strong non-wifi interference is generated on RU 2 during PSDU reception
1016
bandInfo.
fc
=
MHzToHz
(
m_frequency
+ (
m_channelWidth
/ 4));
1017
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(
m_channelWidth
/ 4);
1018
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(
m_channelWidth
/ 4);
1019
bands.clear();
1020
bands.push_back(bandInfo);
1021
1022
Ptr<SpectrumModel>
SpectrumInterferenceRu2 =
Create<SpectrumModel>
(bands);
1023
Ptr<SpectrumValue>
interferencePsdRu2 =
Create<SpectrumValue>
(SpectrumInterferenceRu2);
1024
*interferencePsdRu2 = interferencePower / (
MHzToHz
(
m_channelWidth
/ 2) * 20);
1025
1026
Simulator::Schedule
(
Seconds
(4) +
MicroSeconds
(50),
1027
&
TestDlOfdmaPhyTransmission::GenerateInterference
,
1028
this
,
1029
interferencePsdRu2,
1030
MilliSeconds
(100));
1031
1032
// Since it takes m_expectedPpduDuration to transmit the PPDU,
1033
// both PHYs should be back to IDLE (or CCA_BUSY if interference on the primary 20 MHz) at the
1034
// same time, even the PHY that has no PSDU addressed to it.
1035
Simulator::Schedule
(
Seconds
(4) +
m_expectedPpduDuration
-
NanoSeconds
(1),
1036
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1037
this
,
1038
m_phySta1
,
1039
WifiPhyState::RX);
1040
Simulator::Schedule
(
Seconds
(4) +
m_expectedPpduDuration
-
NanoSeconds
(1),
1041
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1042
this
,
1043
m_phySta2
,
1044
WifiPhyState::RX);
1045
Simulator::Schedule
(
Seconds
(4) +
m_expectedPpduDuration
-
NanoSeconds
(1),
1046
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1047
this
,
1048
m_phySta3
,
1049
WifiPhyState::CCA_BUSY);
1050
Simulator::Schedule
(
Seconds
(4) +
m_expectedPpduDuration
,
1051
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1052
this
,
1053
m_phySta1
,
1054
(
m_channelWidth
>=
MHz_u
{40}) ? WifiPhyState::IDLE
1055
: WifiPhyState::CCA_BUSY);
1056
Simulator::Schedule
(
Seconds
(4) +
m_expectedPpduDuration
,
1057
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1058
this
,
1059
m_phySta2
,
1060
(
m_channelWidth
>=
MHz_u
{40}) ? WifiPhyState::IDLE
1061
: WifiPhyState::CCA_BUSY);
1062
Simulator::Schedule
(
Seconds
(4) +
m_expectedPpduDuration
,
1063
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1064
this
,
1065
m_phySta3
,
1066
(
m_channelWidth
>=
MHz_u
{40}) ? WifiPhyState::IDLE
1067
: WifiPhyState::CCA_BUSY);
1068
1069
// One PSDU of 1000 bytes should have been successfully received by STA 1
1070
Simulator::Schedule
(
Seconds
(4.1),
1071
&
TestDlOfdmaPhyTransmission::CheckResultsSta1
,
1072
this
,
1073
1,
1074
0,
1075
1000);
1076
// One PSDU of 1500 bytes should have been unsuccessfuly received by STA 2 (since interference
1077
// occupies RU 2)
1078
Simulator::Schedule
(
Seconds
(4.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta2
,
this
, 0, 1, 0);
1079
// No PSDU should have been received by STA3
1080
Simulator::Schedule
(
Seconds
(4.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta3
,
this
, 0, 0, 0);
1081
1082
Simulator::Schedule
(
Seconds
(4.5), &
TestDlOfdmaPhyTransmission::ResetResults
,
this
);
1083
1084
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
1085
Simulator::Schedule
(
Seconds
(5), &
TestDlOfdmaPhyTransmission::SendMuPpdu
,
this
, 1, 2);
1086
1087
// A strong non-wifi interference is generated on the full band during PSDU reception
1088
bandInfo.
fc
=
MHzToHz
(
m_frequency
);
1089
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(
m_channelWidth
/ 2);
1090
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(
m_channelWidth
/ 2);
1091
bands.clear();
1092
bands.push_back(bandInfo);
1093
1094
Ptr<SpectrumModel>
SpectrumInterferenceAll =
Create<SpectrumModel>
(bands);
1095
Ptr<SpectrumValue>
interferencePsdAll =
Create<SpectrumValue>
(SpectrumInterferenceAll);
1096
*interferencePsdAll = interferencePower / (
MHzToHz
(
m_channelWidth
) * 20);
1097
1098
Simulator::Schedule
(
Seconds
(5) +
MicroSeconds
(50),
1099
&
TestDlOfdmaPhyTransmission::GenerateInterference
,
1100
this
,
1101
interferencePsdAll,
1102
MilliSeconds
(100));
1103
1104
// Since it takes m_expectedPpduDuration to transmit the PPDU,
1105
// both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
1106
// even the PHY that has no PSDU addressed to it.
1107
Simulator::Schedule
(
Seconds
(5) +
m_expectedPpduDuration
-
NanoSeconds
(1),
1108
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1109
this
,
1110
m_phySta1
,
1111
WifiPhyState::RX);
1112
Simulator::Schedule
(
Seconds
(5) +
m_expectedPpduDuration
-
NanoSeconds
(1),
1113
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1114
this
,
1115
m_phySta2
,
1116
WifiPhyState::RX);
1117
Simulator::Schedule
(
Seconds
(5) +
m_expectedPpduDuration
-
NanoSeconds
(1),
1118
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1119
this
,
1120
m_phySta3
,
1121
WifiPhyState::CCA_BUSY);
1122
Simulator::Schedule
(
Seconds
(5) +
m_expectedPpduDuration
,
1123
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1124
this
,
1125
m_phySta1
,
1126
WifiPhyState::CCA_BUSY);
1127
Simulator::Schedule
(
Seconds
(5) +
m_expectedPpduDuration
,
1128
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1129
this
,
1130
m_phySta2
,
1131
WifiPhyState::CCA_BUSY);
1132
Simulator::Schedule
(
Seconds
(5) +
m_expectedPpduDuration
,
1133
&
TestDlOfdmaPhyTransmission::CheckPhyState
,
1134
this
,
1135
m_phySta3
,
1136
WifiPhyState::CCA_BUSY);
1137
1138
// One PSDU of 1000 bytes should have been unsuccessfuly received by STA 1 (since interference
1139
// occupies RU 1)
1140
Simulator::Schedule
(
Seconds
(5.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta1
,
this
, 0, 1, 0);
1141
// One PSDU of 1500 bytes should have been unsuccessfuly received by STA 2 (since interference
1142
// occupies RU 2)
1143
Simulator::Schedule
(
Seconds
(5.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta2
,
this
, 0, 1, 0);
1144
// No PSDU should have been received by STA3
1145
Simulator::Schedule
(
Seconds
(5.1), &
TestDlOfdmaPhyTransmission::CheckResultsSta3
,
this
, 0, 0, 0);
1146
1147
Simulator::Schedule
(
Seconds
(5.5), &
TestDlOfdmaPhyTransmission::ResetResults
,
this
);
1148
1149
Simulator::Run
();
1150
}
1151
1152
void
1153
TestDlOfdmaPhyTransmission::DoRun
()
1154
{
1155
m_frequency
=
MHz_u
{5180};
1156
m_channelWidth
=
MHz_u
{20};
1157
m_expectedPpduDuration
=
NanoSeconds
(306400);
1158
RunOne
();
1159
1160
m_frequency
=
MHz_u
{5190};
1161
m_channelWidth
=
MHz_u
{40};
1162
m_expectedPpduDuration
=
NanoSeconds
(156800);
1163
RunOne
();
1164
1165
m_frequency
=
MHz_u
{5210};
1166
m_channelWidth
=
MHz_u
{80};
1167
m_expectedPpduDuration
=
NanoSeconds
(102400);
1168
RunOne
();
1169
1170
m_frequency
=
MHz_u
{5250};
1171
m_channelWidth
=
MHz_u
{160};
1172
m_expectedPpduDuration
=
NanoSeconds
(75200);
1173
RunOne
();
1174
1175
Simulator::Destroy
();
1176
}
1177
1178
/**
1179
* @ingroup wifi-test
1180
* @ingroup tests
1181
*
1182
* @brief DL-OFDMA PHY puncturing test
1183
*/
1184
class
TestDlOfdmaPhyPuncturing
:
public
TestCase
1185
{
1186
public
:
1187
TestDlOfdmaPhyPuncturing
();
1188
1189
private
:
1190
void
DoSetup
()
override
;
1191
void
DoTeardown
()
override
;
1192
void
DoRun
()
override
;
1193
1194
/**
1195
* Receive success function for STA 1
1196
* @param psdu the PSDU
1197
* @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1198
* @param txVector the transmit vector
1199
* @param statusPerMpdu reception status per MPDU
1200
*/
1201
void
RxSuccessSta1
(
Ptr<const WifiPsdu>
psdu,
1202
RxSignalInfo
rxSignalInfo,
1203
const
WifiTxVector
& txVector,
1204
const
std::vector<bool>& statusPerMpdu);
1205
1206
/**
1207
* Receive success function for STA 2
1208
* @param psdu the PSDU
1209
* @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1210
* @param txVector the transmit vector
1211
* @param statusPerMpdu reception status per MPDU
1212
*/
1213
void
RxSuccessSta2
(
Ptr<const WifiPsdu>
psdu,
1214
RxSignalInfo
rxSignalInfo,
1215
const
WifiTxVector
& txVector,
1216
const
std::vector<bool>& statusPerMpdu);
1217
1218
/**
1219
* Receive failure function for STA 1
1220
* @param psdu the PSDU
1221
*/
1222
void
RxFailureSta1
(
Ptr<const WifiPsdu>
psdu);
1223
1224
/**
1225
* Receive failure function for STA 2
1226
* @param psdu the PSDU
1227
*/
1228
void
RxFailureSta2
(
Ptr<const WifiPsdu>
psdu);
1229
1230
/**
1231
* Check the results for STA 1
1232
* @param expectedRxSuccess the expected number of RX success
1233
* @param expectedRxFailure the expected number of RX failures
1234
* @param expectedRxBytes the expected number of RX bytes
1235
*/
1236
void
CheckResultsSta1
(
uint32_t
expectedRxSuccess,
1237
uint32_t
expectedRxFailure,
1238
uint32_t
expectedRxBytes);
1239
1240
/**
1241
* Check the results for STA 2
1242
* @param expectedRxSuccess the expected number of RX success
1243
* @param expectedRxFailure the expected number of RX failures
1244
* @param expectedRxBytes the expected number of RX bytes
1245
*/
1246
void
CheckResultsSta2
(
uint32_t
expectedRxSuccess,
1247
uint32_t
expectedRxFailure,
1248
uint32_t
expectedRxBytes);
1249
1250
/**
1251
* Reset the results
1252
*/
1253
void
ResetResults
();
1254
1255
/**
1256
* Send MU-PPDU function
1257
* @param rxStaId1 the ID of the recipient STA for the first PSDU
1258
* @param rxStaId2 the ID of the recipient STA for the second PSDU
1259
* @param puncturedSubchannels indicates for each subchannel whether it is punctured or not. if
1260
* empty, preamble puncturing is not used.
1261
*/
1262
void
SendMuPpdu
(uint16_t rxStaId1,
1263
uint16_t rxStaId2,
1264
const
std::vector<bool>& puncturedSubchannels);
1265
1266
/**
1267
* Generate interference function
1268
* @param interferencePsd the PSD of the interference to be generated
1269
* @param duration the duration of the interference
1270
*/
1271
void
GenerateInterference
(
Ptr<SpectrumValue>
interferencePsd,
Time
duration);
1272
1273
/**
1274
* Stop interference function
1275
*/
1276
void
StopInterference
();
1277
1278
/**
1279
* Run one function
1280
*/
1281
void
RunOne
();
1282
1283
/**
1284
* Schedule now to check the PHY state
1285
* @param phy the PHY
1286
* @param expectedState the expected state of the PHY
1287
*/
1288
void
CheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState);
1289
1290
/**
1291
* Check the PHY state now
1292
* @param phy the PHY
1293
* @param expectedState the expected state of the PHY
1294
*/
1295
void
DoCheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState);
1296
1297
uint32_t
m_countRxSuccessSta1
;
///< count RX success for STA 1
1298
uint32_t
m_countRxSuccessSta2
;
///< count RX success for STA 2
1299
uint32_t
m_countRxFailureSta1
;
///< count RX failure for STA 1
1300
uint32_t
m_countRxFailureSta2
;
///< count RX failure for STA 2
1301
uint32_t
m_countRxBytesSta1
;
///< count RX bytes for STA 1
1302
uint32_t
m_countRxBytesSta2
;
///< count RX bytes for STA 2
1303
1304
Ptr<SpectrumWifiPhy>
m_phyAp
;
///< PHY of AP
1305
Ptr<OfdmaSpectrumWifiPhy>
m_phySta1
;
///< PHY of STA 1
1306
Ptr<OfdmaSpectrumWifiPhy>
m_phySta2
;
///< PHY of STA 2
1307
Ptr<WaveformGenerator>
m_phyInterferer
;
///< PHY of interferer
1308
1309
MHz_u
m_frequency
;
///< frequency
1310
MHz_u
m_channelWidth
;
///< channel width
1311
1312
uint8_t
m_indexSubchannel
;
///< Index of the subchannel (starting from 0) that should contain an
1313
///< interference and be punctured during the test run
1314
1315
Time
m_expectedPpduDuration20Mhz
;
///< expected duration to send MU PPDU on 20 MHz RU
1316
Time
m_expectedPpduDuration40Mhz
;
///< expected duration to send MU PPDU on 40 MHz RU
1317
};
1318
1319
TestDlOfdmaPhyPuncturing::TestDlOfdmaPhyPuncturing
()
1320
:
TestCase
(
"DL-OFDMA PHY puncturing test"
),
1321
m_countRxSuccessSta1(0),
1322
m_countRxSuccessSta2(0),
1323
m_countRxFailureSta1(0),
1324
m_countRxFailureSta2(0),
1325
m_countRxBytesSta1(0),
1326
m_countRxBytesSta2(0),
1327
m_frequency(
MHz_u
{5210}),
1328
m_channelWidth(
MHz_u
{80}),
1329
m_indexSubchannel(0),
1330
m_expectedPpduDuration20Mhz(
NanoSeconds
(156800)),
1331
m_expectedPpduDuration40Mhz(
NanoSeconds
(102400))
1332
{
1333
}
1334
1335
void
1336
TestDlOfdmaPhyPuncturing::ResetResults
()
1337
{
1338
m_countRxSuccessSta1
= 0;
1339
m_countRxSuccessSta2
= 0;
1340
m_countRxFailureSta1
= 0;
1341
m_countRxFailureSta2
= 0;
1342
m_countRxBytesSta1
= 0;
1343
m_countRxBytesSta2
= 0;
1344
}
1345
1346
void
1347
TestDlOfdmaPhyPuncturing::SendMuPpdu
(uint16_t rxStaId1,
1348
uint16_t rxStaId2,
1349
const
std::vector<bool>& puncturedSubchannels)
1350
{
1351
NS_LOG_FUNCTION
(
this
<< rxStaId1 << rxStaId2);
1352
WifiConstPsduMap
psdus;
1353
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
1354
0,
1355
WIFI_PREAMBLE_HE_MU
,
1356
NanoSeconds
(800),
1357
1,
1358
1,
1359
0,
1360
m_channelWidth
,
1361
false
,
1362
false
};
1363
1364
HeRu::RuType
ruType =
1365
puncturedSubchannels.empty()
1366
?
HeRu::RU_484_TONE
1367
: (puncturedSubchannels.at(1) ?
HeRu::RU_242_TONE
:
HeRu::RU_484_TONE
);
1368
HeRu::RuSpec
ru1(ruType, 1,
true
);
1369
txVector.SetRu(ru1, rxStaId1);
1370
txVector.SetMode(
HePhy::GetHeMcs7
(), rxStaId1);
1371
txVector.SetNss(1, rxStaId1);
1372
1373
ruType = puncturedSubchannels.empty()
1374
?
HeRu::RU_484_TONE
1375
: (puncturedSubchannels.at(1) ?
HeRu::RU_484_TONE
:
HeRu::RU_242_TONE
);
1376
HeRu::RuSpec
ru2(ruType,
1377
ruType ==
HeRu::RU_484_TONE
? 2 : (puncturedSubchannels.at(3) ? 3 : 4),
1378
true
);
1379
txVector.SetRu(ru2, rxStaId2);
1380
txVector.SetMode(
HePhy::GetHeMcs9
(), rxStaId2);
1381
txVector.SetNss(1, rxStaId2);
1382
1383
RuAllocation
ruAlloc;
1384
if
(puncturedSubchannels.empty())
1385
{
1386
std::fill_n(std::back_inserter(ruAlloc), 4, 200);
1387
}
1388
else
1389
{
1390
ruAlloc.push_back(puncturedSubchannels.at(1) ? 192 : 200);
1391
ruAlloc.push_back(puncturedSubchannels.at(1) ? 113 : 200);
1392
ruAlloc.push_back(puncturedSubchannels.at(2) ? 113
1393
: (puncturedSubchannels.at(3) ? 192 : 200));
1394
ruAlloc.push_back(puncturedSubchannels.at(2) ? 192
1395
: (puncturedSubchannels.at(3) ? 113 : 200));
1396
}
1397
1398
txVector.SetRuAllocation(ruAlloc, 0);
1399
txVector.SetSigBMode(
VhtPhy::GetVhtMcs5
());
1400
1401
Ptr<Packet>
pkt1 =
Create<Packet>
(1000);
1402
WifiMacHeader
hdr1;
1403
hdr1.
SetType
(
WIFI_MAC_QOSDATA
);
1404
hdr1.
SetQosTid
(0);
1405
hdr1.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:01"
));
1406
hdr1.
SetSequenceNumber
(1);
1407
Ptr<WifiPsdu>
psdu1 =
Create<WifiPsdu>
(pkt1, hdr1);
1408
psdus.insert(std::make_pair(rxStaId1, psdu1));
1409
1410
Ptr<Packet>
pkt2 =
Create<Packet>
(1500);
1411
WifiMacHeader
hdr2;
1412
hdr2.
SetType
(
WIFI_MAC_QOSDATA
);
1413
hdr2.
SetQosTid
(0);
1414
hdr2.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:02"
));
1415
hdr2.
SetSequenceNumber
(2);
1416
Ptr<WifiPsdu>
psdu2 =
Create<WifiPsdu>
(pkt2, hdr2);
1417
psdus.insert(std::make_pair(rxStaId2, psdu2));
1418
1419
if
(!puncturedSubchannels.empty())
1420
{
1421
txVector.SetInactiveSubchannels(puncturedSubchannels);
1422
}
1423
1424
m_phyAp
->Send(psdus, txVector);
1425
}
1426
1427
void
1428
TestDlOfdmaPhyPuncturing::GenerateInterference
(
Ptr<SpectrumValue>
interferencePsd,
Time
duration)
1429
{
1430
NS_LOG_FUNCTION
(
this
<< duration);
1431
m_phyInterferer
->SetTxPowerSpectralDensity(interferencePsd);
1432
m_phyInterferer
->SetPeriod(duration);
1433
m_phyInterferer
->Start();
1434
Simulator::Schedule
(duration, &
TestDlOfdmaPhyPuncturing::StopInterference
,
this
);
1435
}
1436
1437
void
1438
TestDlOfdmaPhyPuncturing::StopInterference
()
1439
{
1440
NS_LOG_FUNCTION
(
this
);
1441
m_phyInterferer
->Stop();
1442
}
1443
1444
void
1445
TestDlOfdmaPhyPuncturing::RxSuccessSta1
(
Ptr<const WifiPsdu>
psdu,
1446
RxSignalInfo
rxSignalInfo,
1447
const
WifiTxVector
& txVector,
1448
const
std::vector<bool>&
/*statusPerMpdu*/
)
1449
{
1450
NS_LOG_FUNCTION
(
this
<< *psdu << rxSignalInfo << txVector);
1451
m_countRxSuccessSta1
++;
1452
m_countRxBytesSta1
+= (psdu->GetSize() - 30);
1453
}
1454
1455
void
1456
TestDlOfdmaPhyPuncturing::RxSuccessSta2
(
Ptr<const WifiPsdu>
psdu,
1457
RxSignalInfo
rxSignalInfo,
1458
const
WifiTxVector
& txVector,
1459
const
std::vector<bool>&
/*statusPerMpdu*/
)
1460
{
1461
NS_LOG_FUNCTION
(
this
<< *psdu << rxSignalInfo << txVector);
1462
m_countRxSuccessSta2
++;
1463
m_countRxBytesSta2
+= (psdu->GetSize() - 30);
1464
}
1465
1466
void
1467
TestDlOfdmaPhyPuncturing::RxFailureSta1
(
Ptr<const WifiPsdu>
psdu)
1468
{
1469
NS_LOG_FUNCTION
(
this
<< *psdu);
1470
m_countRxFailureSta1
++;
1471
}
1472
1473
void
1474
TestDlOfdmaPhyPuncturing::RxFailureSta2
(
Ptr<const WifiPsdu>
psdu)
1475
{
1476
NS_LOG_FUNCTION
(
this
<< *psdu);
1477
m_countRxFailureSta2
++;
1478
}
1479
1480
void
1481
TestDlOfdmaPhyPuncturing::CheckResultsSta1
(
uint32_t
expectedRxSuccess,
1482
uint32_t
expectedRxFailure,
1483
uint32_t
expectedRxBytes)
1484
{
1485
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessSta1
,
1486
expectedRxSuccess,
1487
"The number of successfully received packets by STA 1 is not correct!"
);
1488
NS_TEST_ASSERT_MSG_EQ
(
m_countRxFailureSta1
,
1489
expectedRxFailure,
1490
"The number of unsuccessfuly received packets by STA 1 is not correct!"
);
1491
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesSta1
,
1492
expectedRxBytes,
1493
"The number of bytes received by STA 1 is not correct!"
);
1494
}
1495
1496
void
1497
TestDlOfdmaPhyPuncturing::CheckResultsSta2
(
uint32_t
expectedRxSuccess,
1498
uint32_t
expectedRxFailure,
1499
uint32_t
expectedRxBytes)
1500
{
1501
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessSta2
,
1502
expectedRxSuccess,
1503
"The number of successfully received packets by STA 2 is not correct!"
);
1504
NS_TEST_ASSERT_MSG_EQ
(
m_countRxFailureSta2
,
1505
expectedRxFailure,
1506
"The number of unsuccessfuly received packets by STA 2 is not correct!"
);
1507
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesSta2
,
1508
expectedRxBytes,
1509
"The number of bytes received by STA 2 is not correct!"
);
1510
}
1511
1512
void
1513
TestDlOfdmaPhyPuncturing::CheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState)
1514
{
1515
// This is needed to make sure PHY state will be checked as the last event if a state change
1516
// occurred at the exact same time as the check
1517
Simulator::ScheduleNow
(&
TestDlOfdmaPhyPuncturing::DoCheckPhyState
,
this
, phy, expectedState);
1518
}
1519
1520
void
1521
TestDlOfdmaPhyPuncturing::DoCheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState)
1522
{
1523
WifiPhyState
currentState;
1524
PointerValue
ptr;
1525
phy->GetAttribute(
"State"
, ptr);
1526
Ptr<WifiPhyStateHelper>
state =
DynamicCast<WifiPhyStateHelper>
(ptr.
Get
<
WifiPhyStateHelper
>());
1527
currentState = state->GetState();
1528
NS_LOG_FUNCTION
(
this
<< currentState);
1529
NS_TEST_ASSERT_MSG_EQ
(currentState,
1530
expectedState,
1531
"PHY State "
<< currentState <<
" does not match expected state "
1532
<< expectedState <<
" at "
<<
Simulator::Now
());
1533
}
1534
1535
void
1536
TestDlOfdmaPhyPuncturing::DoSetup
()
1537
{
1538
Ptr<MultiModelSpectrumChannel>
spectrumChannel =
CreateObject<MultiModelSpectrumChannel>
();
1539
Ptr<FriisPropagationLossModel>
lossModel =
CreateObject<FriisPropagationLossModel>
();
1540
lossModel->SetFrequency(
MHzToHz
(
m_frequency
));
1541
spectrumChannel->AddPropagationLossModel(lossModel);
1542
Ptr<ConstantSpeedPropagationDelayModel>
delayModel =
1543
CreateObject<ConstantSpeedPropagationDelayModel>
();
1544
spectrumChannel->SetPropagationDelayModel(delayModel);
1545
1546
Ptr<Node>
apNode =
CreateObject<Node>
();
1547
Ptr<WifiNetDevice>
apDev =
CreateObject<WifiNetDevice>
();
1548
m_phyAp
=
CreateObject<SpectrumWifiPhy>
();
1549
Ptr<InterferenceHelper>
apInterferenceHelper =
CreateObject<InterferenceHelper>
();
1550
m_phyAp
->SetInterferenceHelper(apInterferenceHelper);
1551
Ptr<ErrorRateModel>
apErrorModel =
CreateObject<NistErrorRateModel>
();
1552
m_phyAp
->SetErrorRateModel(apErrorModel);
1553
m_phyAp
->SetDevice(apDev);
1554
m_phyAp
->AddChannel(spectrumChannel);
1555
m_phyAp
->ConfigureStandard(
WIFI_STANDARD_80211ax
);
1556
Ptr<ConstantPositionMobilityModel>
apMobility =
CreateObject<ConstantPositionMobilityModel>
();
1557
m_phyAp
->SetMobility(apMobility);
1558
apDev->SetPhy(
m_phyAp
);
1559
apNode->AggregateObject(apMobility);
1560
apNode->AddDevice(apDev);
1561
1562
Ptr<Node>
sta1Node =
CreateObject<Node>
();
1563
Ptr<WifiNetDevice>
sta1Dev =
CreateObject<WifiNetDevice>
();
1564
m_phySta1
=
CreateObject<OfdmaSpectrumWifiPhy>
(1);
1565
Ptr<InterferenceHelper>
sta1InterferenceHelper =
CreateObject<InterferenceHelper>
();
1566
m_phySta1
->
SetInterferenceHelper
(sta1InterferenceHelper);
1567
Ptr<ErrorRateModel>
sta1ErrorModel =
CreateObject<NistErrorRateModel>
();
1568
m_phySta1
->
SetErrorRateModel
(sta1ErrorModel);
1569
m_phySta1
->
SetDevice
(sta1Dev);
1570
m_phySta1
->
AddChannel
(spectrumChannel);
1571
m_phySta1
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
1572
m_phySta1
->
SetReceiveOkCallback
(
MakeCallback
(&
TestDlOfdmaPhyPuncturing::RxSuccessSta1
,
this
));
1573
m_phySta1
->
SetReceiveErrorCallback
(
1574
MakeCallback
(&
TestDlOfdmaPhyPuncturing::RxFailureSta1
,
this
));
1575
Ptr<ConstantPositionMobilityModel>
sta1Mobility =
CreateObject<ConstantPositionMobilityModel>
();
1576
m_phySta1
->
SetMobility
(sta1Mobility);
1577
sta1Dev->SetPhy(
m_phySta1
);
1578
sta1Node->AggregateObject(sta1Mobility);
1579
sta1Node->AddDevice(sta1Dev);
1580
1581
Ptr<Node>
sta2Node =
CreateObject<Node>
();
1582
Ptr<WifiNetDevice>
sta2Dev =
CreateObject<WifiNetDevice>
();
1583
m_phySta2
=
CreateObject<OfdmaSpectrumWifiPhy>
(2);
1584
Ptr<InterferenceHelper>
sta2InterferenceHelper =
CreateObject<InterferenceHelper>
();
1585
m_phySta2
->
SetInterferenceHelper
(sta2InterferenceHelper);
1586
Ptr<ErrorRateModel>
sta2ErrorModel =
CreateObject<NistErrorRateModel>
();
1587
m_phySta2
->
SetErrorRateModel
(sta2ErrorModel);
1588
m_phySta2
->
SetDevice
(sta2Dev);
1589
m_phySta2
->
AddChannel
(spectrumChannel);
1590
m_phySta2
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
1591
m_phySta2
->
SetReceiveOkCallback
(
MakeCallback
(&
TestDlOfdmaPhyPuncturing::RxSuccessSta2
,
this
));
1592
m_phySta2
->
SetReceiveErrorCallback
(
1593
MakeCallback
(&
TestDlOfdmaPhyPuncturing::RxFailureSta2
,
this
));
1594
Ptr<ConstantPositionMobilityModel>
sta2Mobility =
CreateObject<ConstantPositionMobilityModel>
();
1595
m_phySta2
->
SetMobility
(sta2Mobility);
1596
sta2Dev->SetPhy(
m_phySta2
);
1597
sta2Node->AggregateObject(sta2Mobility);
1598
sta2Node->AddDevice(sta2Dev);
1599
1600
Ptr<Node>
interfererNode =
CreateObject<Node>
();
1601
Ptr<NonCommunicatingNetDevice>
interfererDev =
CreateObject<NonCommunicatingNetDevice>
();
1602
m_phyInterferer
=
CreateObject<WaveformGenerator>
();
1603
m_phyInterferer
->SetDevice(interfererDev);
1604
m_phyInterferer
->SetChannel(spectrumChannel);
1605
m_phyInterferer
->SetDutyCycle(1);
1606
interfererNode->AddDevice(interfererDev);
1607
}
1608
1609
void
1610
TestDlOfdmaPhyPuncturing::DoTeardown
()
1611
{
1612
m_phyAp
->Dispose();
1613
m_phyAp
=
nullptr
;
1614
m_phySta1
->
Dispose
();
1615
m_phySta1
=
nullptr
;
1616
m_phySta2
->
Dispose
();
1617
m_phySta2
=
nullptr
;
1618
m_phyInterferer
->
Dispose
();
1619
m_phyInterferer
=
nullptr
;
1620
}
1621
1622
void
1623
TestDlOfdmaPhyPuncturing::RunOne
()
1624
{
1625
RngSeedManager::SetSeed
(1);
1626
RngSeedManager::SetRun
(1);
1627
int64_t streamNumber = 0;
1628
m_phyAp
->AssignStreams(streamNumber);
1629
m_phySta1
->
AssignStreams
(streamNumber);
1630
m_phySta2
->
AssignStreams
(streamNumber);
1631
1632
auto
channelNum =
WifiPhyOperatingChannel::FindFirst
(0,
1633
m_frequency
,
1634
m_channelWidth
,
1635
WIFI_STANDARD_80211ax
,
1636
WIFI_PHY_BAND_5GHZ
)
1637
->number;
1638
1639
m_phyAp
->SetOperatingChannel(
1640
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
1641
m_phySta1
->
SetOperatingChannel
(
1642
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
1643
m_phySta2
->
SetOperatingChannel
(
1644
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
1645
1646
// A strong non-wifi interference is generated on selected 20 MHz subchannel for the whole
1647
// duration of the test run
1648
BandInfo
bandInfo;
1649
bandInfo.
fc
=
MHzToHz
(
m_frequency
- (
m_channelWidth
/ 2) + 10 + (
m_indexSubchannel
* 20));
1650
// Occupy half of the RU to make sure we do not have some power allocated to the subcarriers on
1651
// the border of another RU
1652
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(5);
1653
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(5);
1654
Bands
bands;
1655
bands.push_back(bandInfo);
1656
1657
auto
spectrumInterference =
Create<SpectrumModel>
(bands);
1658
auto
interferencePsd =
Create<SpectrumValue>
(spectrumInterference);
1659
Watt_u
interferencePower{0.1};
1660
*interferencePsd = interferencePower / 10e6;
1661
1662
Simulator::Schedule
(
Seconds
(0),
1663
&
TestDlOfdmaPhyPuncturing::GenerateInterference
,
1664
this
,
1665
interferencePsd,
1666
Seconds
(3));
1667
1668
//---------------------------------------------------------------------------
1669
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 2 without preamble puncturing:
1670
Simulator::Schedule
(
Seconds
(1),
1671
&
TestDlOfdmaPhyPuncturing::SendMuPpdu
,
1672
this
,
1673
1,
1674
2,
1675
std::vector<bool>{});
1676
1677
// Since it takes m_expectedPpduDuration to transmit the PPDU,
1678
// both PHYs should be back to IDLE at the same time.
1679
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration40Mhz
-
NanoSeconds
(1),
1680
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1681
this
,
1682
m_phySta1
,
1683
WifiPhyState::RX);
1684
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration40Mhz
-
NanoSeconds
(1),
1685
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1686
this
,
1687
m_phySta2
,
1688
WifiPhyState::RX);
1689
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration40Mhz
,
1690
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1691
this
,
1692
m_phySta1
,
1693
WifiPhyState::IDLE);
1694
Simulator::Schedule
(
Seconds
(1) +
m_expectedPpduDuration40Mhz
,
1695
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1696
this
,
1697
m_phySta2
,
1698
WifiPhyState::IDLE);
1699
1700
if
(
m_indexSubchannel
< 2)
// interference in RU 1
1701
{
1702
// One PSDU of 1000 bytes should have been unsuccessfuly received by STA 1
1703
Simulator::Schedule
(
Seconds
(1.1),
1704
&
TestDlOfdmaPhyPuncturing::CheckResultsSta1
,
1705
this
,
1706
0,
1707
1,
1708
0);
1709
// One PSDU of 1500 bytes should have been successfully received by STA 2
1710
Simulator::Schedule
(
Seconds
(1.1),
1711
&
TestDlOfdmaPhyPuncturing::CheckResultsSta2
,
1712
this
,
1713
1,
1714
0,
1715
1500);
1716
}
1717
else
// interference in RU 2
1718
{
1719
// One PSDU of 1000 bytes should have been successfully received by STA 1
1720
Simulator::Schedule
(
Seconds
(1.1),
1721
&
TestDlOfdmaPhyPuncturing::CheckResultsSta1
,
1722
this
,
1723
1,
1724
0,
1725
1000);
1726
// One PSDU of 1500 bytes should have been unsuccessfuly received by STA 2
1727
Simulator::Schedule
(
Seconds
(1.1),
1728
&
TestDlOfdmaPhyPuncturing::CheckResultsSta2
,
1729
this
,
1730
0,
1731
1,
1732
0);
1733
}
1734
1735
Simulator::Schedule
(
Seconds
(1.5), &
TestDlOfdmaPhyPuncturing::ResetResults
,
this
);
1736
1737
//---------------------------------------------------------------------------
1738
// Send MU PPDU with two PSDUs addressed to STA 1 and STA 2 with preamble puncturing:
1739
// the punctured 20 MHz subchannel is the one that has interference
1740
std::vector<bool> puncturedSubchannels;
1741
const
auto
num20MhzSubchannels =
Count20MHzSubchannels
(
m_channelWidth
);
1742
for
(std::size_t i = 0; i < num20MhzSubchannels; ++i)
1743
{
1744
if
(i ==
m_indexSubchannel
)
1745
{
1746
puncturedSubchannels.push_back(
true
);
1747
}
1748
else
1749
{
1750
puncturedSubchannels.push_back(
false
);
1751
}
1752
}
1753
Simulator::Schedule
(
Seconds
(2),
1754
&
TestDlOfdmaPhyPuncturing::SendMuPpdu
,
1755
this
,
1756
1,
1757
2,
1758
puncturedSubchannels);
1759
1760
// Since it takes m_expectedPpduDuration to transmit the PPDU,
1761
// both PHYs should be back to IDLE at the same time.
1762
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration20Mhz
-
NanoSeconds
(1),
1763
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1764
this
,
1765
m_phySta1
,
1766
WifiPhyState::RX);
1767
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration20Mhz
-
NanoSeconds
(1),
1768
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1769
this
,
1770
m_phySta2
,
1771
WifiPhyState::RX);
1772
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration20Mhz
,
1773
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1774
this
,
1775
m_phySta1
,
1776
WifiPhyState::IDLE);
1777
Simulator::Schedule
(
Seconds
(2) +
m_expectedPpduDuration20Mhz
,
1778
&
TestDlOfdmaPhyPuncturing::CheckPhyState
,
1779
this
,
1780
m_phySta2
,
1781
WifiPhyState::IDLE);
1782
1783
// One PSDU of 1000 bytes should have been successfully received by STA 1
1784
Simulator::Schedule
(
Seconds
(2.1),
1785
&
TestDlOfdmaPhyPuncturing::CheckResultsSta1
,
1786
this
,
1787
1,
1788
0,
1789
1000);
1790
// One PSDU of 1500 bytes should have been successfully received by STA 2
1791
Simulator::Schedule
(
Seconds
(2.1),
1792
&
TestDlOfdmaPhyPuncturing::CheckResultsSta2
,
1793
this
,
1794
1,
1795
0,
1796
1500);
1797
1798
Simulator::Schedule
(
Seconds
(2.5), &
TestDlOfdmaPhyPuncturing::ResetResults
,
this
);
1799
1800
Simulator::Run
();
1801
}
1802
1803
void
1804
TestDlOfdmaPhyPuncturing::DoRun
()
1805
{
1806
// test all 20 MHz subchannels in the 80 MHz operation channel except the primary one which
1807
// cannot be punctured
1808
for
(
auto
index : {1, 2, 3})
1809
{
1810
m_indexSubchannel
= index;
1811
RunOne
();
1812
}
1813
Simulator::Destroy
();
1814
}
1815
1816
/**
1817
* @ingroup wifi-test
1818
* @ingroup tests
1819
*
1820
* @brief UL-OFDMA PPDU UID attribution test
1821
*/
1822
class
TestUlOfdmaPpduUid
:
public
TestCase
1823
{
1824
public
:
1825
TestUlOfdmaPpduUid
();
1826
~TestUlOfdmaPpduUid
()
override
;
1827
1828
private
:
1829
void
DoSetup
()
override
;
1830
void
DoTeardown
()
override
;
1831
void
DoRun
()
override
;
1832
1833
/**
1834
* Transmitted PPDU information function for AP
1835
* @param uid the UID of the transmitted PPDU
1836
*/
1837
void
TxPpduAp
(uint64_t uid);
1838
/**
1839
* Transmitted PPDU information function for STA 1
1840
* @param uid the UID of the transmitted PPDU
1841
*/
1842
void
TxPpduSta1
(uint64_t uid);
1843
/**
1844
* Transmitted PPDU information function for STA 2
1845
* @param uid the UID of the transmitted PPDU
1846
*/
1847
void
TxPpduSta2
(uint64_t uid);
1848
/**
1849
* Reset the global PPDU UID counter in WifiPhy
1850
*/
1851
void
ResetPpduUid
();
1852
1853
/**
1854
* Send MU-PPDU toward both STAs.
1855
*/
1856
void
SendMuPpdu
();
1857
/**
1858
* Send TB-PPDU from both STAs.
1859
*/
1860
void
SendTbPpdu
();
1861
/**
1862
* Send SU-PPDU function
1863
* @param txStaId the ID of the sending STA
1864
*/
1865
void
SendSuPpdu
(uint16_t txStaId);
1866
1867
/**
1868
* Check the UID of the transmitted PPDU
1869
* @param staId the STA-ID of the PHY (0 for AP)
1870
* @param expectedUid the expected UID
1871
*/
1872
void
CheckUid
(uint16_t staId, uint64_t expectedUid);
1873
1874
Ptr<OfdmaSpectrumWifiPhy>
m_phyAp
;
///< PHY of AP
1875
Ptr<OfdmaSpectrumWifiPhy>
m_phySta1
;
///< PHY of STA 1
1876
Ptr<OfdmaSpectrumWifiPhy>
m_phySta2
;
///< PHY of STA 2
1877
1878
uint64_t
m_ppduUidAp
;
///< UID of PPDU transmitted by AP
1879
uint64_t
m_ppduUidSta1
;
///< UID of PPDU transmitted by STA1
1880
uint64_t
m_ppduUidSta2
;
///< UID of PPDU transmitted by STA2
1881
};
1882
1883
TestUlOfdmaPpduUid::TestUlOfdmaPpduUid
()
1884
:
TestCase
(
"UL-OFDMA PPDU UID attribution test"
),
1885
m_ppduUidAp(UINT64_MAX),
1886
m_ppduUidSta1(UINT64_MAX),
1887
m_ppduUidSta2(UINT64_MAX)
1888
{
1889
}
1890
1891
TestUlOfdmaPpduUid::~TestUlOfdmaPpduUid
()
1892
{
1893
}
1894
1895
void
1896
TestUlOfdmaPpduUid::DoSetup
()
1897
{
1898
Ptr<MultiModelSpectrumChannel>
spectrumChannel =
CreateObject<MultiModelSpectrumChannel>
();
1899
Ptr<FriisPropagationLossModel>
lossModel =
CreateObject<FriisPropagationLossModel>
();
1900
lossModel->SetFrequency(
DEFAULT_FREQUENCY
);
1901
spectrumChannel->AddPropagationLossModel(lossModel);
1902
Ptr<ConstantSpeedPropagationDelayModel>
delayModel =
1903
CreateObject<ConstantSpeedPropagationDelayModel>
();
1904
spectrumChannel->SetPropagationDelayModel(delayModel);
1905
1906
Ptr<Node>
apNode =
CreateObject<Node>
();
1907
Ptr<WifiNetDevice>
apDev =
CreateObject<WifiNetDevice>
();
1908
m_phyAp
=
CreateObject<OfdmaSpectrumWifiPhy>
(0);
1909
Ptr<InterferenceHelper>
apInterferenceHelper =
CreateObject<InterferenceHelper>
();
1910
m_phyAp
->
SetInterferenceHelper
(apInterferenceHelper);
1911
Ptr<ErrorRateModel>
apErrorModel =
CreateObject<NistErrorRateModel>
();
1912
m_phyAp
->
SetErrorRateModel
(apErrorModel);
1913
m_phyAp
->
AddChannel
(spectrumChannel);
1914
m_phyAp
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
1915
auto
channelNum =
WifiPhyOperatingChannel::FindFirst
(0,
1916
DEFAULT_FREQUENCY
,
1917
DEFAULT_CHANNEL_WIDTH
,
1918
WIFI_STANDARD_80211ax
,
1919
WIFI_PHY_BAND_5GHZ
)
1920
->number;
1921
m_phyAp
->
SetOperatingChannel
(
1922
WifiPhy::ChannelTuple
{channelNum,
DEFAULT_CHANNEL_WIDTH
,
WIFI_PHY_BAND_5GHZ
, 0});
1923
m_phyAp
->
SetDevice
(apDev);
1924
m_phyAp
->
TraceConnectWithoutContext
(
"TxPpduUid"
,
1925
MakeCallback
(&
TestUlOfdmaPpduUid::TxPpduAp
,
this
));
1926
Ptr<ConstantPositionMobilityModel>
apMobility =
CreateObject<ConstantPositionMobilityModel>
();
1927
m_phyAp
->
SetMobility
(apMobility);
1928
apDev->SetPhy(
m_phyAp
);
1929
apNode->AggregateObject(apMobility);
1930
apNode->AddDevice(apDev);
1931
apDev->SetStandard(
WIFI_STANDARD_80211ax
);
1932
apDev->SetHeConfiguration(
CreateObject<HeConfiguration>
());
1933
1934
Ptr<Node>
sta1Node =
CreateObject<Node>
();
1935
Ptr<WifiNetDevice>
sta1Dev =
CreateObject<WifiNetDevice>
();
1936
m_phySta1
=
CreateObject<OfdmaSpectrumWifiPhy>
(1);
1937
Ptr<InterferenceHelper>
sta1InterferenceHelper =
CreateObject<InterferenceHelper>
();
1938
m_phySta1
->
SetInterferenceHelper
(sta1InterferenceHelper);
1939
Ptr<ErrorRateModel>
sta1ErrorModel =
CreateObject<NistErrorRateModel>
();
1940
m_phySta1
->
SetErrorRateModel
(sta1ErrorModel);
1941
m_phySta1
->
AddChannel
(spectrumChannel);
1942
m_phySta1
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
1943
m_phySta1
->
SetOperatingChannel
(
1944
WifiPhy::ChannelTuple
{channelNum,
DEFAULT_CHANNEL_WIDTH
,
WIFI_PHY_BAND_5GHZ
, 0});
1945
m_phySta1
->
SetDevice
(sta1Dev);
1946
m_phySta1
->
TraceConnectWithoutContext
(
"TxPpduUid"
,
1947
MakeCallback
(&
TestUlOfdmaPpduUid::TxPpduSta1
,
this
));
1948
Ptr<ConstantPositionMobilityModel>
sta1Mobility =
CreateObject<ConstantPositionMobilityModel>
();
1949
m_phySta1
->
SetMobility
(sta1Mobility);
1950
sta1Dev->SetPhy(
m_phySta1
);
1951
sta1Node->AggregateObject(sta1Mobility);
1952
sta1Node->AddDevice(sta1Dev);
1953
1954
Ptr<Node>
sta2Node =
CreateObject<Node>
();
1955
Ptr<WifiNetDevice>
sta2Dev =
CreateObject<WifiNetDevice>
();
1956
m_phySta2
=
CreateObject<OfdmaSpectrumWifiPhy>
(2);
1957
Ptr<InterferenceHelper>
sta2InterferenceHelper =
CreateObject<InterferenceHelper>
();
1958
m_phySta2
->
SetInterferenceHelper
(sta2InterferenceHelper);
1959
Ptr<ErrorRateModel>
sta2ErrorModel =
CreateObject<NistErrorRateModel>
();
1960
m_phySta2
->
SetErrorRateModel
(sta2ErrorModel);
1961
m_phySta2
->
AddChannel
(spectrumChannel);
1962
m_phySta2
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
1963
m_phySta2
->
SetOperatingChannel
(
1964
WifiPhy::ChannelTuple
{channelNum,
DEFAULT_CHANNEL_WIDTH
,
WIFI_PHY_BAND_5GHZ
, 0});
1965
m_phySta2
->
SetDevice
(sta2Dev);
1966
m_phySta2
->
TraceConnectWithoutContext
(
"TxPpduUid"
,
1967
MakeCallback
(&
TestUlOfdmaPpduUid::TxPpduSta2
,
this
));
1968
Ptr<ConstantPositionMobilityModel>
sta2Mobility =
CreateObject<ConstantPositionMobilityModel>
();
1969
m_phySta2
->
SetMobility
(sta2Mobility);
1970
sta2Dev->SetPhy(
m_phySta2
);
1971
sta2Node->AggregateObject(sta2Mobility);
1972
sta2Node->AddDevice(sta2Dev);
1973
}
1974
1975
void
1976
TestUlOfdmaPpduUid::DoTeardown
()
1977
{
1978
m_phyAp
->
Dispose
();
1979
m_phyAp
=
nullptr
;
1980
m_phySta1
->
Dispose
();
1981
m_phySta1
=
nullptr
;
1982
m_phySta2
->
Dispose
();
1983
m_phySta2
=
nullptr
;
1984
}
1985
1986
void
1987
TestUlOfdmaPpduUid::CheckUid
(uint16_t staId, uint64_t expectedUid)
1988
{
1989
uint64_t uid;
1990
std::string device;
1991
switch
(staId)
1992
{
1993
case
0:
1994
uid =
m_ppduUidAp
;
1995
device =
"AP"
;
1996
break
;
1997
case
1:
1998
uid =
m_ppduUidSta1
;
1999
device =
"STA1"
;
2000
break
;
2001
case
2:
2002
uid =
m_ppduUidSta2
;
2003
device =
"STA2"
;
2004
break
;
2005
default
:
2006
NS_ABORT_MSG
(
"Unexpected STA-ID"
);
2007
}
2008
NS_TEST_ASSERT_MSG_EQ
(uid,
2009
expectedUid,
2010
"UID "
<< uid <<
" does not match expected one "
<< expectedUid <<
" for "
2011
<< device <<
" at "
<<
Simulator::Now
());
2012
}
2013
2014
void
2015
TestUlOfdmaPpduUid::TxPpduAp
(uint64_t uid)
2016
{
2017
NS_LOG_FUNCTION
(
this
<< uid);
2018
m_ppduUidAp
= uid;
2019
}
2020
2021
void
2022
TestUlOfdmaPpduUid::TxPpduSta1
(uint64_t uid)
2023
{
2024
NS_LOG_FUNCTION
(
this
<< uid);
2025
m_ppduUidSta1
= uid;
2026
}
2027
2028
void
2029
TestUlOfdmaPpduUid::TxPpduSta2
(uint64_t uid)
2030
{
2031
NS_LOG_FUNCTION
(
this
<< uid);
2032
m_ppduUidSta2
= uid;
2033
}
2034
2035
void
2036
TestUlOfdmaPpduUid::ResetPpduUid
()
2037
{
2038
NS_LOG_FUNCTION
(
this
);
2039
m_phyAp
->
SetPpduUid
(0);
// one is enough since it's a global attribute
2040
}
2041
2042
void
2043
TestUlOfdmaPpduUid::SendMuPpdu
()
2044
{
2045
WifiConstPsduMap
psdus;
2046
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
2047
0,
2048
WIFI_PREAMBLE_HE_MU
,
2049
NanoSeconds
(800),
2050
1,
2051
1,
2052
0,
2053
DEFAULT_CHANNEL_WIDTH
,
2054
false
,
2055
false
};
2056
2057
uint16_t rxStaId1 = 1;
2058
HeRu::RuSpec
ru1(
HeRu::RU_106_TONE
, 1,
true
);
2059
txVector.SetRu(ru1, rxStaId1);
2060
txVector.SetMode(
HePhy::GetHeMcs7
(), rxStaId1);
2061
txVector.SetNss(1, rxStaId1);
2062
2063
uint16_t rxStaId2 = 2;
2064
HeRu::RuSpec
ru2(
HeRu::RU_106_TONE
, 2,
true
);
2065
txVector.SetRu(ru2, rxStaId2);
2066
txVector.SetMode(
HePhy::GetHeMcs9
(), rxStaId2);
2067
txVector.SetNss(1, rxStaId2);
2068
txVector.SetSigBMode(
VhtPhy::GetVhtMcs5
());
2069
txVector.SetRuAllocation({96}, 0);
2070
2071
Ptr<Packet>
pkt1 =
Create<Packet>
(1000);
2072
WifiMacHeader
hdr1;
2073
hdr1.
SetType
(
WIFI_MAC_QOSDATA
);
2074
hdr1.
SetQosTid
(0);
2075
hdr1.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:01"
));
2076
hdr1.
SetSequenceNumber
(1);
2077
Ptr<WifiPsdu>
psdu1 =
Create<WifiPsdu>
(pkt1, hdr1);
2078
psdus.insert(std::make_pair(rxStaId1, psdu1));
2079
2080
Ptr<Packet>
pkt2 =
Create<Packet>
(1500);
2081
WifiMacHeader
hdr2;
2082
hdr2.
SetType
(
WIFI_MAC_QOSDATA
);
2083
hdr2.
SetQosTid
(0);
2084
hdr2.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:02"
));
2085
hdr2.
SetSequenceNumber
(2);
2086
Ptr<WifiPsdu>
psdu2 =
Create<WifiPsdu>
(pkt2, hdr2);
2087
psdus.insert(std::make_pair(rxStaId2, psdu2));
2088
2089
m_phyAp
->
Send
(psdus, txVector);
2090
}
2091
2092
void
2093
TestUlOfdmaPpduUid::SendTbPpdu
()
2094
{
2095
WifiConstPsduMap
psdus1;
2096
WifiConstPsduMap
psdus2;
2097
2098
WifiTxVector
txVector1{
HePhy::GetHeMcs7
(),
2099
0,
2100
WIFI_PREAMBLE_HE_TB
,
2101
NanoSeconds
(1600),
2102
1,
2103
1,
2104
0,
2105
DEFAULT_CHANNEL_WIDTH
,
2106
false
,
2107
false
};
2108
WifiTxVector
txVector2{txVector1};
2109
WifiTxVector
trigVector{txVector2};
2110
2111
uint16_t rxStaId1 = 1;
2112
HeRu::RuSpec
ru1(
HeRu::RU_106_TONE
, 1,
false
);
2113
txVector1.SetRu(ru1, rxStaId1);
2114
txVector1.SetMode(
HePhy::GetHeMcs7
(), rxStaId1);
2115
txVector1.SetNss(1, rxStaId1);
2116
trigVector.SetRu(ru1, rxStaId1);
2117
trigVector.SetMode(
HePhy::GetHeMcs7
(), rxStaId1);
2118
trigVector.SetNss(1, rxStaId1);
2119
2120
auto
pkt1 =
Create<Packet>
(1000);
2121
WifiMacHeader
hdr1;
2122
hdr1.
SetType
(
WIFI_MAC_QOSDATA
);
2123
hdr1.
SetQosTid
(0);
2124
hdr1.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:00"
));
2125
hdr1.
SetSequenceNumber
(1);
2126
auto
psdu1 =
Create<WifiPsdu>
(pkt1, hdr1);
2127
psdus1.insert(std::make_pair(rxStaId1, psdu1));
2128
2129
uint16_t rxStaId2 = 2;
2130
HeRu::RuSpec
ru2(
HeRu::RU_106_TONE
, 2,
false
);
2131
txVector2.SetRu(ru2, rxStaId2);
2132
txVector2.SetMode(
HePhy::GetHeMcs9
(), rxStaId2);
2133
txVector2.SetNss(1, rxStaId2);
2134
trigVector.SetRu(ru2, rxStaId2);
2135
trigVector.SetMode(
HePhy::GetHeMcs9
(), rxStaId2);
2136
trigVector.SetNss(1, rxStaId2);
2137
2138
auto
pkt2 =
Create<Packet>
(1500);
2139
WifiMacHeader
hdr2;
2140
hdr2.
SetType
(
WIFI_MAC_QOSDATA
);
2141
hdr2.
SetQosTid
(0);
2142
hdr2.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:00"
));
2143
hdr2.
SetSequenceNumber
(2);
2144
auto
psdu2 =
Create<WifiPsdu>
(pkt2, hdr2);
2145
psdus2.insert(std::make_pair(rxStaId2, psdu2));
2146
2147
const
auto
txDuration1 =
m_phySta1
->
CalculateTxDuration
(psdu1->GetSize(),
2148
txVector1,
2149
m_phySta1
->
GetPhyBand
(),
2150
rxStaId1);
2151
const
auto
txDuration2 =
m_phySta2
->
CalculateTxDuration
(psdu2->GetSize(),
2152
txVector2,
2153
m_phySta1
->
GetPhyBand
(),
2154
rxStaId2);
2155
const
auto
txDuration = std::max(txDuration1, txDuration2);
2156
2157
txVector1.SetLength(
2158
HePhy::ConvertHeTbPpduDurationToLSigLength
(txDuration, txVector1,
m_phySta1
->
GetPhyBand
())
2159
.first);
2160
txVector2.SetLength(
2161
HePhy::ConvertHeTbPpduDurationToLSigLength
(txDuration, txVector2,
m_phySta2
->
GetPhyBand
())
2162
.first);
2163
2164
auto
hePhyAp =
DynamicCast<HePhy>
(
m_phyAp
->
GetPhyEntity
(
WIFI_MOD_CLASS_HE
));
2165
hePhyAp->SetTrigVector(trigVector, txDuration);
2166
2167
m_phySta1
->
Send
(psdus1, txVector1);
2168
m_phySta2
->
Send
(psdus2, txVector2);
2169
}
2170
2171
void
2172
TestUlOfdmaPpduUid::SendSuPpdu
(uint16_t txStaId)
2173
{
2174
WifiConstPsduMap
psdus;
2175
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
2176
0,
2177
WIFI_PREAMBLE_HE_SU
,
2178
NanoSeconds
(800),
2179
1,
2180
1,
2181
0,
2182
DEFAULT_CHANNEL_WIDTH
,
2183
false
,
2184
false
};
2185
2186
auto
pkt =
Create<Packet>
(1000);
2187
WifiMacHeader
hdr;
2188
hdr.
SetType
(
WIFI_MAC_QOSDATA
);
2189
hdr.
SetQosTid
(0);
2190
hdr.
SetAddr1
(
Mac48Address::GetBroadcast
());
2191
hdr.
SetSequenceNumber
(1);
2192
auto
psdu =
Create<WifiPsdu>
(pkt, hdr);
2193
psdus.insert(std::make_pair(
SU_STA_ID
, psdu));
2194
2195
switch
(txStaId)
2196
{
2197
case
0:
2198
m_phyAp
->
Send
(psdus, txVector);
2199
break
;
2200
case
1:
2201
m_phySta1
->
Send
(psdus, txVector);
2202
break
;
2203
case
2:
2204
m_phySta2
->
Send
(psdus, txVector);
2205
break
;
2206
default
:
2207
NS_ABORT_MSG
(
"Unexpected STA-ID"
);
2208
}
2209
}
2210
2211
void
2212
TestUlOfdmaPpduUid::DoRun
()
2213
{
2214
RngSeedManager::SetSeed
(1);
2215
RngSeedManager::SetRun
(1);
2216
int64_t streamNumber = 0;
2217
m_phyAp
->
AssignStreams
(streamNumber);
2218
m_phySta1
->
AssignStreams
(streamNumber);
2219
m_phySta2
->
AssignStreams
(streamNumber);
2220
2221
// Reset PPDU UID so as not to be dependent on previously executed test cases,
2222
// since global attribute will be changed).
2223
ResetPpduUid
();
2224
2225
// Send HE MU PPDU with two PSDUs addressed to STA 1 and STA 2.
2226
// PPDU UID should be equal to 0 (the first counter value).
2227
Simulator::Schedule
(
Seconds
(1), &
TestUlOfdmaPpduUid::SendMuPpdu
,
this
);
2228
Simulator::Schedule
(
Seconds
(1), &
TestUlOfdmaPpduUid::CheckUid
,
this
, 0, 0);
2229
2230
// Send HE SU PPDU from AP.
2231
// PPDU UID should be incremented since this is a new PPDU.
2232
Simulator::Schedule
(
Seconds
(1.1), &
TestUlOfdmaPpduUid::SendSuPpdu
,
this
, 0);
2233
Simulator::Schedule
(
Seconds
(1.1), &
TestUlOfdmaPpduUid::CheckUid
,
this
, 0, 1);
2234
2235
// Send HE TB PPDU from STAs to AP.
2236
// PPDU UID should NOT be incremented since HE TB PPDUs reuse the UID of the immediately
2237
// preceding correctly received PPDU (which normally contains the trigger frame).
2238
Simulator::Schedule
(
Seconds
(1.15), &
TestUlOfdmaPpduUid::SendTbPpdu
,
this
);
2239
Simulator::Schedule
(
Seconds
(1.15), &
TestUlOfdmaPpduUid::CheckUid
,
this
, 1, 1);
2240
Simulator::Schedule
(
Seconds
(1.15), &
TestUlOfdmaPpduUid::CheckUid
,
this
, 2, 1);
2241
2242
// Send HE SU PPDU from STA1.
2243
// PPDU UID should be incremented since this is a new PPDU.
2244
Simulator::Schedule
(
Seconds
(1.2), &
TestUlOfdmaPpduUid::SendSuPpdu
,
this
, 1);
2245
Simulator::Schedule
(
Seconds
(1.2), &
TestUlOfdmaPpduUid::CheckUid
,
this
, 1, 2);
2246
2247
Simulator::Run
();
2248
Simulator::Destroy
();
2249
}
2250
2251
/**
2252
* @ingroup wifi-test
2253
* @ingroup tests
2254
*
2255
* @brief UL-OFDMA multiple RX events test
2256
*/
2257
class
TestMultipleHeTbPreambles
:
public
TestCase
2258
{
2259
public
:
2260
TestMultipleHeTbPreambles
();
2261
~TestMultipleHeTbPreambles
()
override
;
2262
2263
private
:
2264
void
DoSetup
()
override
;
2265
void
DoTeardown
()
override
;
2266
void
DoRun
()
override
;
2267
2268
/**
2269
* Receive HE TB PPDU function.
2270
*
2271
* @param uid the UID used to identify a set of HE TB PPDUs belonging to the same UL-MU
2272
* transmission
2273
* @param staId the STA ID
2274
* @param txPower the TX power
2275
* @param payloadSize the size of the payload in bytes
2276
*/
2277
void
RxHeTbPpdu
(uint64_t uid, uint16_t staId,
Watt_u
txPower,
size_t
payloadSize);
2278
2279
/**
2280
* Receive OFDMA part of HE TB PPDU function.
2281
* Immediately schedules DoRxHeTbPpduOfdmaPart.
2282
*
2283
* @param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
2284
*/
2285
void
RxHeTbPpduOfdmaPart
(
Ptr<WifiSpectrumSignalParameters>
rxParamsOfdma);
2286
/**
2287
* Receive OFDMA part of HE TB PPDU function.
2288
* Actual reception call.
2289
*
2290
* @param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
2291
*/
2292
void
DoRxHeTbPpduOfdmaPart
(
Ptr<WifiSpectrumSignalParameters>
rxParamsOfdma);
2293
2294
/**
2295
* RX dropped function
2296
* @param p the packet
2297
* @param reason the reason
2298
*/
2299
void
RxDropped
(
Ptr<const Packet>
p,
WifiPhyRxfailureReason
reason);
2300
2301
/**
2302
* Reset function
2303
*/
2304
void
Reset
();
2305
2306
/**
2307
* Check the received HE TB preambles
2308
* @param nEvents the number of events created by the PHY
2309
* @param uids the vector of expected UIDs
2310
*/
2311
void
CheckHeTbPreambles
(
size_t
nEvents, std::vector<uint64_t> uids);
2312
2313
/**
2314
* Check the number of bytes dropped
2315
* @param expectedBytesDropped the expected number of bytes dropped
2316
*/
2317
void
CheckBytesDropped
(
size_t
expectedBytesDropped);
2318
2319
Ptr<OfdmaSpectrumWifiPhy>
m_phy
;
///< Phy
2320
2321
uint64_t
m_totalBytesDropped
;
///< total number of dropped bytes
2322
WifiTxVector
m_trigVector
;
///< TRIGVECTOR
2323
};
2324
2325
TestMultipleHeTbPreambles::TestMultipleHeTbPreambles
()
2326
:
TestCase
(
"UL-OFDMA multiple RX events test"
),
2327
m_totalBytesDropped(0),
2328
m_trigVector(
HePhy
::GetHeMcs7(),
2329
0,
2330
WIFI_PREAMBLE_HE_TB
,
2331
NanoSeconds
(1600),
2332
1,
2333
1,
2334
0,
2335
DEFAULT_CHANNEL_WIDTH
,
2336
false,
2337
false)
2338
{
2339
}
2340
2341
TestMultipleHeTbPreambles::~TestMultipleHeTbPreambles
()
2342
{
2343
}
2344
2345
void
2346
TestMultipleHeTbPreambles::Reset
()
2347
{
2348
NS_LOG_FUNCTION
(
this
);
2349
m_totalBytesDropped
= 0;
2350
// We have to reset PHY here since we do not trigger OFDMA payload RX event in this test
2351
m_phy
->
Reset
();
2352
m_trigVector
.
GetHeMuUserInfoMap
().clear();
2353
}
2354
2355
void
2356
TestMultipleHeTbPreambles::RxDropped
(
Ptr<const Packet>
p,
WifiPhyRxfailureReason
reason)
2357
{
2358
NS_LOG_FUNCTION
(
this
<< p << reason);
2359
m_totalBytesDropped
+= (p->GetSize() - 30);
2360
}
2361
2362
void
2363
TestMultipleHeTbPreambles::CheckHeTbPreambles
(
size_t
nEvents, std::vector<uint64_t> uids)
2364
{
2365
auto
events =
m_phy
->
GetCurrentPreambleEvents
();
2366
NS_TEST_ASSERT_MSG_EQ
(events.size(), nEvents,
"The number of UL MU events is not correct!"
);
2367
for
(
const
auto
& uid : uids)
2368
{
2369
auto
pair = std::make_pair(uid,
WIFI_PREAMBLE_HE_TB
);
2370
auto
it = events.find(pair);
2371
bool
found = (it != events.end());
2372
NS_TEST_ASSERT_MSG_EQ
(found,
2373
true
,
2374
"HE TB PPDU with UID "
<< uid <<
" has not been received!"
);
2375
}
2376
}
2377
2378
void
2379
TestMultipleHeTbPreambles::CheckBytesDropped
(
size_t
expectedBytesDropped)
2380
{
2381
NS_TEST_ASSERT_MSG_EQ
(
m_totalBytesDropped
,
2382
expectedBytesDropped,
2383
"The number of dropped bytes is not correct!"
);
2384
}
2385
2386
void
2387
TestMultipleHeTbPreambles::RxHeTbPpdu
(uint64_t uid,
2388
uint16_t staId,
2389
Watt_u
txPower,
2390
size_t
payloadSize)
2391
{
2392
WifiConstPsduMap
psdus;
2393
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
2394
0,
2395
WIFI_PREAMBLE_HE_TB
,
2396
NanoSeconds
(1600),
2397
1,
2398
1,
2399
0,
2400
DEFAULT_CHANNEL_WIDTH
,
2401
false
,
2402
false
};
2403
2404
HeRu::RuSpec
ru(
HeRu::RU_106_TONE
, staId,
false
);
2405
txVector.SetRu(ru, staId);
2406
txVector.SetMode(
HePhy::GetHeMcs7
(), staId);
2407
txVector.SetNss(1, staId);
2408
2409
m_trigVector
.
SetHeMuUserInfo
(staId, {ru, 7, 1});
2410
2411
auto
pkt =
Create<Packet>
(payloadSize);
2412
WifiMacHeader
hdr;
2413
hdr.
SetType
(
WIFI_MAC_QOSDATA
);
2414
hdr.
SetQosTid
(0);
2415
hdr.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:00"
));
2416
hdr.
SetSequenceNumber
(1);
2417
auto
psdu =
Create<WifiPsdu>
(pkt, hdr);
2418
psdus.insert(std::make_pair(staId, psdu));
2419
2420
auto
ppduDuration =
2421
m_phy
->
CalculateTxDuration
(psdu->GetSize(), txVector,
m_phy
->
GetPhyBand
(), staId);
2422
auto
ppdu =
Create<HePpdu>
(psdus,
2423
txVector,
2424
m_phy
->
GetOperatingChannel
(),
2425
ppduDuration,
2426
uid,
2427
HePpdu::PSD_NON_HE_PORTION
);
2428
2429
// Send non-OFDMA part
2430
const
auto
nonOfdmaDuration =
m_phy
->
GetHePhy
()->CalculateNonHeDurationForHeTb(txVector);
2431
const
auto
centerFrequency =
2432
m_phy
->
GetHePhy
()->GetCenterFrequenciesForNonHePart(ppdu, staId).front();
2433
MHz_u
ruWidth =
HeRu::GetBandwidth
(txVector.GetRu(staId).GetRuType());
2434
MHz_u
channelWidth = ruWidth <
MHz_u
{20} ?
MHz_u
{20} : ruWidth;
2435
Ptr<SpectrumValue>
rxPsd =
WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity
(
2436
centerFrequency,
2437
channelWidth,
2438
txPower,
2439
m_phy
->
GetGuardBandwidth
(channelWidth));
2440
auto
rxParams =
Create<WifiSpectrumSignalParameters>
();
2441
rxParams->psd = rxPsd;
2442
rxParams->txPhy =
nullptr
;
2443
rxParams->duration = nonOfdmaDuration;
2444
rxParams->ppdu = ppdu;
2445
2446
uint16_t length;
2447
std::tie(length, ppduDuration) =
2448
HePhy::ConvertHeTbPpduDurationToLSigLength
(ppduDuration, txVector,
m_phy
->
GetPhyBand
());
2449
txVector.SetLength(length);
2450
m_trigVector
.
SetLength
(length);
2451
auto
hePhy =
DynamicCast<HePhy>
(
m_phy
->
GetLatestPhyEntity
());
2452
hePhy->SetTrigVector(
m_trigVector
, ppduDuration);
2453
ppdu->ResetTxVector();
2454
m_phy
->
StartRx
(rxParams,
nullptr
);
2455
2456
// Schedule OFDMA part
2457
auto
ppduOfdma =
DynamicCast<HePpdu>
(ppdu->Copy());
// since flag will be modified
2458
ppduOfdma->SetTxPsdFlag(
HePpdu::PSD_HE_PORTION
);
2459
const
auto
band =
m_phy
->
GetHePhy
()->GetRuBandForRx(txVector, staId);
2460
auto
rxPsdOfdma =
2461
WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity
({
DEFAULT_FREQUENCY
},
2462
DEFAULT_CHANNEL_WIDTH
,
2463
txPower,
2464
DEFAULT_GUARD_WIDTH
,
2465
band.indices);
2466
auto
rxParamsOfdma =
Create<WifiSpectrumSignalParameters>
();
2467
rxParamsOfdma->psd = rxPsd;
2468
rxParamsOfdma->txPhy =
nullptr
;
2469
rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
2470
rxParamsOfdma->ppdu = ppduOfdma;
2471
Simulator::Schedule
(nonOfdmaDuration,
2472
&
TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart
,
2473
this
,
2474
rxParamsOfdma);
2475
}
2476
2477
void
2478
TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart
(
Ptr<WifiSpectrumSignalParameters>
rxParamsOfdma)
2479
{
2480
Simulator::ScheduleNow
(&
TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart
,
this
, rxParamsOfdma);
2481
}
2482
2483
void
2484
TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart
(
Ptr<WifiSpectrumSignalParameters>
rxParamsOfdma)
2485
{
2486
// This is needed to make sure the OFDMA part is started as the last event since HE-SIG-A should
2487
// end at the exact same time as the start For normal WifiNetDevices, this the reception of the
2488
// OFDMA part is scheduled after end of HE-SIG-A decoding.
2489
m_phy
->
StartRx
(rxParamsOfdma,
nullptr
);
2490
}
2491
2492
void
2493
TestMultipleHeTbPreambles::DoSetup
()
2494
{
2495
Ptr<MultiModelSpectrumChannel>
spectrumChannel =
CreateObject<MultiModelSpectrumChannel>
();
2496
Ptr<Node>
node =
CreateObject<Node>
();
2497
Ptr<WifiNetDevice>
dev =
CreateObject<WifiNetDevice>
();
2498
dev->SetStandard(
WIFI_STANDARD_80211ax
);
2499
m_phy
=
CreateObject<OfdmaSpectrumWifiPhy>
(0);
2500
Ptr<InterferenceHelper>
interferenceHelper =
CreateObject<InterferenceHelper>
();
2501
Ptr<ErrorRateModel>
error =
CreateObject<NistErrorRateModel>
();
2502
auto
mac =
CreateObjectWithAttributes<ApWifiMac>
(
2503
"Txop"
,
2504
PointerValue
(
CreateObjectWithAttributes<Txop>
(
"AcIndex"
,
StringValue
(
"AC_BE_NQOS"
))));
2505
mac->SetAttribute(
"BeaconGeneration"
,
BooleanValue
(
false
));
2506
dev->SetMac(mac);
2507
m_phy
->
SetInterferenceHelper
(interferenceHelper);
2508
m_phy
->
SetErrorRateModel
(error);
2509
m_phy
->
AddChannel
(spectrumChannel);
2510
m_phy
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
2511
m_phy
->
SetOperatingChannel
(
WifiPhy::ChannelTuple
{
DEFAULT_CHANNEL_NUMBER
,
2512
DEFAULT_CHANNEL_WIDTH
,
2513
WIFI_PHY_BAND_5GHZ
,
2514
0});
2515
m_phy
->
TraceConnectWithoutContext
(
"PhyRxDrop"
,
2516
MakeCallback
(&
TestMultipleHeTbPreambles::RxDropped
,
this
));
2517
m_phy
->
SetDevice
(dev);
2518
Ptr<ThresholdPreambleDetectionModel>
preambleDetectionModel =
2519
CreateObject<ThresholdPreambleDetectionModel>
();
2520
preambleDetectionModel->SetAttribute(
"Threshold"
,
DoubleValue
(4));
2521
preambleDetectionModel->SetAttribute(
"MinimumRssi"
,
DoubleValue
(-82));
2522
m_phy
->
SetPreambleDetectionModel
(preambleDetectionModel);
2523
Ptr<HeConfiguration>
heConfiguration =
CreateObject<HeConfiguration>
();
2524
heConfiguration->m_maxTbPpduDelay =
NanoSeconds
(400);
2525
dev->SetHeConfiguration(heConfiguration);
2526
dev->SetPhy(
m_phy
);
2527
node->AddDevice(dev);
2528
}
2529
2530
void
2531
TestMultipleHeTbPreambles::DoTeardown
()
2532
{
2533
m_phy
->
Dispose
();
2534
m_phy
=
nullptr
;
2535
}
2536
2537
void
2538
TestMultipleHeTbPreambles::DoRun
()
2539
{
2540
RngSeedManager::SetSeed
(1);
2541
RngSeedManager::SetRun
(1);
2542
int64_t streamNumber = 0;
2543
m_phy
->
AssignStreams
(streamNumber);
2544
2545
Watt_u
txPower{0.01};
2546
2547
{
2548
// Verify a single UL MU transmission with two stations belonging to the same BSS
2549
std::vector<uint64_t> uids{0};
2550
Simulator::Schedule
(
Seconds
(1),
2551
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2552
this
,
2553
uids[0],
2554
1,
2555
txPower,
2556
1001);
2557
Simulator::Schedule
(
Seconds
(1) +
NanoSeconds
(100),
2558
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2559
this
,
2560
uids[0],
2561
2,
2562
txPower,
2563
1002);
2564
// Check that we received a single UL MU transmission with the corresponding UID
2565
Simulator::Schedule
(
Seconds
(1) +
MicroSeconds
(1),
2566
&
TestMultipleHeTbPreambles::CheckHeTbPreambles
,
2567
this
,
2568
1,
2569
uids);
2570
Simulator::Schedule
(
Seconds
(1.5), &
TestMultipleHeTbPreambles::Reset
,
this
);
2571
}
2572
2573
{
2574
// Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where
2575
// the second transmission arrives during the preamble detection window and with half the
2576
// power of the first transmission.
2577
std::vector<uint64_t> uids{1, 2};
2578
Simulator::Schedule
(
Seconds
(2),
2579
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2580
this
,
2581
uids[0],
2582
1,
2583
txPower,
2584
1001);
2585
Simulator::Schedule
(
Seconds
(2) +
NanoSeconds
(100),
2586
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2587
this
,
2588
uids[0],
2589
2,
2590
txPower,
2591
1002);
2592
Simulator::Schedule
(
Seconds
(2) +
NanoSeconds
(200),
2593
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2594
this
,
2595
uids[1],
2596
1,
2597
txPower / 2,
2598
1003);
2599
Simulator::Schedule
(
Seconds
(2) +
NanoSeconds
(300),
2600
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2601
this
,
2602
uids[1],
2603
2,
2604
txPower / 2,
2605
1004);
2606
// Check that we received the correct reception of 2 UL MU transmissions with the
2607
// corresponding UIDs
2608
Simulator::Schedule
(
Seconds
(2) +
MicroSeconds
(1),
2609
&
TestMultipleHeTbPreambles::CheckHeTbPreambles
,
2610
this
,
2611
2,
2612
uids);
2613
Simulator::Schedule
(
Seconds
(2.5), &
TestMultipleHeTbPreambles::Reset
,
this
);
2614
// TODO: verify PPDUs from second UL MU transmission are dropped
2615
}
2616
2617
{
2618
// Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where
2619
// the second transmission arrives during the preamble detection window and with twice the
2620
// power of the first transmission.
2621
std::vector<uint64_t> uids{3, 4};
2622
Simulator::Schedule
(
Seconds
(3),
2623
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2624
this
,
2625
uids[0],
2626
1,
2627
txPower / 2,
2628
1001);
2629
Simulator::Schedule
(
Seconds
(3) +
NanoSeconds
(100),
2630
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2631
this
,
2632
uids[0],
2633
2,
2634
txPower / 2,
2635
1002);
2636
Simulator::Schedule
(
Seconds
(3) +
NanoSeconds
(200),
2637
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2638
this
,
2639
uids[1],
2640
1,
2641
txPower,
2642
1003);
2643
Simulator::Schedule
(
Seconds
(3) +
NanoSeconds
(300),
2644
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2645
this
,
2646
uids[1],
2647
2,
2648
txPower,
2649
1004);
2650
// Check that we received the correct reception of 2 UL MU transmissions with the
2651
// corresponding UIDs
2652
Simulator::Schedule
(
Seconds
(3) +
MicroSeconds
(1),
2653
&
TestMultipleHeTbPreambles::CheckHeTbPreambles
,
2654
this
,
2655
2,
2656
uids);
2657
Simulator::Schedule
(
Seconds
(3.5), &
TestMultipleHeTbPreambles::Reset
,
this
);
2658
// TODO: verify PPDUs from first UL MU transmission are dropped
2659
}
2660
2661
{
2662
// Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where
2663
// the second transmission arrives during PHY header reception and with the same power as
2664
// the first transmission.
2665
std::vector<uint64_t> uids{5, 6};
2666
Simulator::Schedule
(
Seconds
(4),
2667
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2668
this
,
2669
uids[0],
2670
1,
2671
txPower,
2672
1001);
2673
Simulator::Schedule
(
Seconds
(4) +
NanoSeconds
(100),
2674
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2675
this
,
2676
uids[0],
2677
2,
2678
txPower,
2679
1002);
2680
Simulator::Schedule
(
Seconds
(4) +
MicroSeconds
(5),
2681
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2682
this
,
2683
uids[1],
2684
1,
2685
txPower,
2686
1003);
2687
Simulator::Schedule
(
Seconds
(4) +
MicroSeconds
(5) +
NanoSeconds
(100),
2688
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2689
this
,
2690
uids[1],
2691
2,
2692
txPower,
2693
1004);
2694
// Check that we received the correct reception of the first UL MU transmission with the
2695
// corresponding UID (second one dropped)
2696
Simulator::Schedule
(
Seconds
(4) +
MicroSeconds
(10),
2697
&
TestMultipleHeTbPreambles::CheckHeTbPreambles
,
2698
this
,
2699
1,
2700
std::vector<uint64_t>{uids[0]});
2701
// The packets of the second UL MU transmission should have been dropped
2702
Simulator::Schedule
(
Seconds
(4) +
MicroSeconds
(10),
2703
&
TestMultipleHeTbPreambles::CheckBytesDropped
,
2704
this
,
2705
1003 + 1004);
2706
Simulator::Schedule
(
Seconds
(4.5), &
TestMultipleHeTbPreambles::Reset
,
this
);
2707
}
2708
2709
{
2710
// Verify the correct reception of one UL MU transmission out of 2 with two stations per
2711
// BSS, where the second transmission arrives during payload reception and with the same
2712
// power as the first transmission.
2713
std::vector<uint64_t> uids{7, 8};
2714
Simulator::Schedule
(
Seconds
(5),
2715
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2716
this
,
2717
uids[0],
2718
1,
2719
txPower,
2720
1001);
2721
Simulator::Schedule
(
Seconds
(5) +
NanoSeconds
(100),
2722
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2723
this
,
2724
uids[0],
2725
2,
2726
txPower,
2727
1002);
2728
Simulator::Schedule
(
Seconds
(5) +
MicroSeconds
(50),
2729
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2730
this
,
2731
uids[1],
2732
1,
2733
txPower,
2734
1003);
2735
Simulator::Schedule
(
Seconds
(5) +
MicroSeconds
(50) +
NanoSeconds
(100),
2736
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2737
this
,
2738
uids[1],
2739
2,
2740
txPower,
2741
1004);
2742
// Check that we received the correct reception of the first UL MU transmission with the
2743
// corresponding UID (second one dropped)
2744
Simulator::Schedule
(
Seconds
(5) +
MicroSeconds
(100),
2745
&
TestMultipleHeTbPreambles::CheckHeTbPreambles
,
2746
this
,
2747
1,
2748
std::vector<uint64_t>{uids[0]});
2749
// The packets of the second UL MU transmission should have been dropped
2750
Simulator::Schedule
(
Seconds
(5) +
MicroSeconds
(100),
2751
&
TestMultipleHeTbPreambles::CheckBytesDropped
,
2752
this
,
2753
1003 + 1004);
2754
Simulator::Schedule
(
Seconds
(5.5), &
TestMultipleHeTbPreambles::Reset
,
this
);
2755
}
2756
2757
{
2758
// Verify the correct reception of a single UL MU transmission with two stations belonging
2759
// to the same BSS, and the second PPDU arrives 500ns after the first PPDU, i.e. it exceeds
2760
// the configured delay spread of 400ns
2761
std::vector<uint64_t> uids{9};
2762
Simulator::Schedule
(
Seconds
(6),
2763
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2764
this
,
2765
uids[0],
2766
1,
2767
txPower,
2768
1001);
2769
Simulator::Schedule
(
Seconds
(6) +
NanoSeconds
(500),
2770
&
TestMultipleHeTbPreambles::RxHeTbPpdu
,
2771
this
,
2772
uids[0],
2773
2,
2774
txPower,
2775
1002);
2776
// Check that we received a single UL MU transmission with the corresponding UID
2777
Simulator::Schedule
(
Seconds
(6) +
MicroSeconds
(1),
2778
&
TestMultipleHeTbPreambles::CheckHeTbPreambles
,
2779
this
,
2780
1,
2781
uids);
2782
// The first packet of 1001 bytes should be dropped because preamble is not detected after
2783
// 4us (because the PPDU that arrived at 500ns is interfering): the second HE TB PPDU is
2784
// acting as interference since it arrived after the maximum allowed 400ns. Obviously, that
2785
// second packet of 1002 bytes is dropped as well.
2786
Simulator::Schedule
(
Seconds
(6) +
MicroSeconds
(5),
2787
&
TestMultipleHeTbPreambles::CheckBytesDropped
,
2788
this
,
2789
1001 + 1002);
2790
Simulator::Schedule
(
Seconds
(6.5), &
TestMultipleHeTbPreambles::Reset
,
this
);
2791
}
2792
2793
Simulator::Run
();
2794
Simulator::Destroy
();
2795
}
2796
2797
/**
2798
* @ingroup wifi-test
2799
* @ingroup tests
2800
*
2801
* @brief PHY listener for OFDMA tests
2802
*/
2803
class
OfdmaTestPhyListener
:
public
ns3::WifiPhyListener
2804
{
2805
public
:
2806
OfdmaTestPhyListener
() =
default
;
2807
2808
void
NotifyRxStart
(
Time
duration)
override
2809
{
2810
NS_LOG_FUNCTION
(
this
<< duration);
2811
m_lastRxStart
=
Simulator::Now
();
2812
++
m_notifyRxStart
;
2813
m_lastRxSuccess
=
false
;
2814
}
2815
2816
void
NotifyRxEndOk
()
override
2817
{
2818
NS_LOG_FUNCTION
(
this
);
2819
m_lastRxEnd
=
Simulator::Now
();
2820
++
m_notifyRxEnd
;
2821
m_lastRxSuccess
=
true
;
2822
}
2823
2824
void
NotifyRxEndError
()
override
2825
{
2826
NS_LOG_FUNCTION
(
this
);
2827
m_lastRxEnd
=
Simulator::Now
();
2828
++
m_notifyRxEnd
;
2829
m_lastRxSuccess
=
false
;
2830
}
2831
2832
void
NotifyTxStart
(
Time
duration,
dBm_u
txPower)
override
2833
{
2834
NS_LOG_FUNCTION
(
this
<< duration << txPower);
2835
}
2836
2837
void
NotifyCcaBusyStart
(
Time
duration,
2838
WifiChannelListType
channelType,
2839
const
std::vector<Time>&
/*per20MhzDurations*/
)
override
2840
{
2841
NS_LOG_FUNCTION
(
this
<< duration << channelType);
2842
}
2843
2844
void
NotifySwitchingStart
(
Time
duration)
override
2845
{
2846
}
2847
2848
void
NotifySleep
()
override
2849
{
2850
}
2851
2852
void
NotifyOff
()
override
2853
{
2854
}
2855
2856
void
NotifyWakeup
()
override
2857
{
2858
}
2859
2860
void
NotifyOn
()
override
2861
{
2862
}
2863
2864
/**
2865
* Reset function.
2866
*/
2867
void
Reset
()
2868
{
2869
m_notifyRxStart
= 0;
2870
m_notifyRxEnd
= 0;
2871
m_lastRxStart
=
Seconds
(0);
2872
m_lastRxEnd
=
Seconds
(0);
2873
m_lastRxSuccess
=
false
;
2874
}
2875
2876
/**
2877
* Return the number of RX start notifications that has been received since the last reset.
2878
* @return the number of RX start notifications that has been received
2879
*/
2880
uint32_t
GetNumRxStartNotifications
()
const
2881
{
2882
return
m_notifyRxStart
;
2883
}
2884
2885
/**
2886
* Return the number of RX end notifications that has been received since the last reset.
2887
* @return the number of RX end notifications that has been received
2888
*/
2889
uint32_t
GetNumRxEndNotifications
()
const
2890
{
2891
return
m_notifyRxEnd
;
2892
}
2893
2894
/**
2895
* Return the time at which the last RX start notification has been received.
2896
* @return the time at which the last RX start notification has been received
2897
*/
2898
Time
GetLastRxStartNotification
()
const
2899
{
2900
return
m_lastRxStart
;
2901
}
2902
2903
/**
2904
* Return the time at which the last RX end notification has been received.
2905
* @return the time at which the last RX end notification has been received
2906
*/
2907
Time
GetLastRxEndNotification
()
const
2908
{
2909
return
m_lastRxEnd
;
2910
}
2911
2912
/**
2913
* Return whether last RX has been successful.
2914
* @return true if last RX has been successful, false otherwise
2915
*/
2916
bool
IsLastRxSuccess
()
const
2917
{
2918
return
m_lastRxSuccess
;
2919
}
2920
2921
private
:
2922
uint32_t
m_notifyRxStart
{0};
///< count number of RX start notifications
2923
uint32_t
m_notifyRxEnd
{0};
///< count number of RX end notifications
2924
Time
m_lastRxStart
{
Seconds
(0)};
///< last time a RX start notification has been received
2925
Time
m_lastRxEnd
{
Seconds
(0)};
///< last time a RX end notification has been received
2926
bool
m_lastRxSuccess
{
false
};
///< flag whether last RX has been successful
2927
};
2928
2929
/**
2930
* @ingroup wifi-test
2931
* @ingroup tests
2932
*
2933
* @brief UL-OFDMA PHY test
2934
*/
2935
class
TestUlOfdmaPhyTransmission
:
public
TestCase
2936
{
2937
public
:
2938
/**
2939
* Erroneous info included in a TRIGVECTOR
2940
*/
2941
enum
TrigVectorInfo
2942
{
2943
NONE
= 0,
2944
CHANNEL_WIDTH
,
2945
UL_LENGTH
,
2946
AID
,
2947
};
2948
2949
TestUlOfdmaPhyTransmission
();
2950
~TestUlOfdmaPhyTransmission
()
override
;
2951
2952
private
:
2953
void
DoSetup
()
override
;
2954
void
DoTeardown
()
override
;
2955
void
DoRun
()
override
;
2956
2957
/**
2958
* Get TXVECTOR for HE TB PPDU.
2959
* @param txStaId the ID of the TX STA
2960
* @param index the RU index used for the transmission
2961
* @param bssColor the BSS color of the TX STA
2962
* @return the TXVECTOR for HE TB PPDU
2963
*/
2964
WifiTxVector
GetTxVectorForHeTbPpdu
(uint16_t txStaId,
2965
std::size_t index,
2966
uint8_t bssColor)
const
;
2967
/**
2968
* Set TRIGVECTOR for HE TB PPDU
2969
*
2970
* @param bssColor the BSS color of the TX STA
2971
* @param error the erroneous info (if any) in the TRIGVECTOR to set
2972
*/
2973
void
SetTrigVector
(uint8_t bssColor,
TrigVectorInfo
error);
2974
/**
2975
* Send HE TB PPDU function
2976
* @param txStaId the ID of the TX STA
2977
* @param index the RU index used for the transmission
2978
* @param payloadSize the size of the payload in bytes
2979
* @param uid the UID of the trigger frame that is initiating this transmission
2980
* @param bssColor the BSS color of the TX STA
2981
* @param incrementUid whether UID shall be incremented
2982
*/
2983
void
SendHeTbPpdu
(uint16_t txStaId,
2984
std::size_t index,
2985
std::size_t payloadSize,
2986
uint64_t uid,
2987
uint8_t bssColor,
2988
bool
incrementUid);
2989
2990
/**
2991
* Send HE SU PPDU function
2992
* @param txStaId the ID of the TX STA
2993
* @param payloadSize the size of the payload in bytes
2994
* @param uid the UID of the trigger frame that is initiating this transmission
2995
* @param bssColor the BSS color of the TX STA
2996
*/
2997
void
SendHeSuPpdu
(uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
2998
2999
/**
3000
* Set the BSS color
3001
* @param phy the PHY
3002
* @param bssColor the BSS color
3003
*/
3004
void
SetBssColor
(
Ptr<WifiPhy>
phy, uint8_t bssColor);
3005
3006
/**
3007
* Set the PSD limit
3008
* @param phy the PHY
3009
* @param psdLimit the PSD limit
3010
*/
3011
void
SetPsdLimit
(
Ptr<WifiPhy>
phy,
dBm_per_MHz_u
psdLimit);
3012
3013
/**
3014
* Generate interference function
3015
* @param interferencePsd the PSD of the interference to be generated
3016
* @param duration the duration of the interference
3017
*/
3018
void
GenerateInterference
(
Ptr<SpectrumValue>
interferencePsd,
Time
duration);
3019
/**
3020
* Stop interference function
3021
*/
3022
void
StopInterference
();
3023
3024
/**
3025
* Run one function
3026
*/
3027
void
RunOne
();
3028
3029
/**
3030
* Check the received PSDUs from STA1
3031
* @param expectedSuccess the expected number of success
3032
* @param expectedFailures the expected number of failures
3033
* @param expectedBytes the expected number of bytes
3034
*/
3035
void
CheckRxFromSta1
(
uint32_t
expectedSuccess,
3036
uint32_t
expectedFailures,
3037
uint32_t
expectedBytes);
3038
3039
/**
3040
* Check the received PSDUs from STA2
3041
* @param expectedSuccess the expected number of success
3042
* @param expectedFailures the expected number of failures
3043
* @param expectedBytes the expected number of bytes
3044
*/
3045
void
CheckRxFromSta2
(
uint32_t
expectedSuccess,
3046
uint32_t
expectedFailures,
3047
uint32_t
expectedBytes);
3048
3049
/**
3050
* Check the received power for the non-OFDMA of the HE TB PPDUs over the given band
3051
* @param phy the PHY
3052
* @param band the indices of the band over which the power is measured
3053
* @param expectedRxPower the expected received power
3054
*/
3055
void
CheckNonOfdmaRxPower
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
3056
WifiSpectrumBandInfo
band,
3057
Watt_u
expectedRxPower);
3058
/**
3059
* Check the received power for the OFDMA part of the HE TB PPDUs over the given band
3060
* @param phy the PHY
3061
* @param band the indices of the band over which the power is measured
3062
* @param expectedRxPower the expected received power
3063
*/
3064
void
CheckOfdmaRxPower
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
3065
WifiSpectrumBandInfo
band,
3066
Watt_u
expectedRxPower);
3067
3068
/**
3069
* Verify all events are cleared at end of TX or RX
3070
*/
3071
void
VerifyEventsCleared
();
3072
3073
/**
3074
* Check the PHY state
3075
* @param phy the PHY
3076
* @param expectedState the expected state of the PHY
3077
*/
3078
void
CheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState);
3079
/// @copydoc CheckPhyState
3080
void
DoCheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState);
3081
3082
/**
3083
* Check the the number of RX start notifications at the AP as well as the last time a RX start
3084
* has been notified
3085
* @param expectedNotifications the expected number of RX start notifications at the AP
3086
* @param expectedLastNotification the expected time of the last RX start notification at the AP
3087
*/
3088
void
CheckApRxStart
(
uint32_t
expectedNotifications,
Time
expectedLastNotification);
3089
/**
3090
* Check the the number of RX end notifications at the AP as well as the last time a RX end has
3091
* been notified
3092
* @param expectedNotifications the expected number of RX end notifications at the AP
3093
* @param expectedLastNotification the expected time of the last RX end notification at the AP
3094
* @param expectedSuccess true if the last RX notification indicates a success, false otherwise
3095
*/
3096
void
CheckApRxEnd
(
uint32_t
expectedNotifications,
3097
Time
expectedLastNotification,
3098
bool
expectedSuccess);
3099
3100
/**
3101
* Reset function
3102
*/
3103
void
Reset
();
3104
3105
/**
3106
* Receive success function
3107
* @param psdu the PSDU
3108
* @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
3109
* @param txVector the transmit vector
3110
* @param statusPerMpdu reception status per MPDU
3111
*/
3112
void
RxSuccess
(
Ptr<const WifiPsdu>
psdu,
3113
RxSignalInfo
rxSignalInfo,
3114
const
WifiTxVector
& txVector,
3115
const
std::vector<bool>& statusPerMpdu);
3116
3117
/**
3118
* Receive failure function
3119
* @param psdu the PSDU
3120
*/
3121
void
RxFailure
(
Ptr<const WifiPsdu>
psdu);
3122
3123
/**
3124
* Schedule test to perform.
3125
* The interference generation should be scheduled apart.
3126
*
3127
* @param delay the reference delay to schedule the events
3128
* @param solicited flag indicating if HE TB PPDUs were solicited by the AP
3129
* @param expectedStateAtEnd the expected state of the PHY at the end of the reception
3130
* @param expectedSuccessFromSta1 the expected number of success from STA 1
3131
* @param expectedFailuresFromSta1 the expected number of failures from STA 1
3132
* @param expectedBytesFromSta1 the expected number of bytes from STA 1
3133
* @param expectedSuccessFromSta2 the expected number of success from STA 2
3134
* @param expectedFailuresFromSta2 the expected number of failures from STA 2
3135
* @param expectedBytesFromSta2 the expected number of bytes from STA 2
3136
* @param scheduleTxSta1 flag indicating to schedule a HE TB PPDU from STA 1
3137
* @param ulTimeDifference delay between HE TB PPDU from STA 1 and HE TB PPDU from STA 2
3138
* are received
3139
* @param expectedStateBeforeEnd the expected state of the PHY before the end of the
3140
* transmission
3141
* @param error the erroneous info (if any) in the TRIGVECTOR to set
3142
*/
3143
void
ScheduleTest
(
Time
delay,
3144
bool
solicited,
3145
WifiPhyState
expectedStateAtEnd,
3146
uint32_t
expectedSuccessFromSta1,
3147
uint32_t
expectedFailuresFromSta1,
3148
uint32_t
expectedBytesFromSta1,
3149
uint32_t
expectedSuccessFromSta2,
3150
uint32_t
expectedFailuresFromSta2,
3151
uint32_t
expectedBytesFromSta2,
3152
bool
scheduleTxSta1 =
true
,
3153
Time
ulTimeDifference =
Seconds
(0),
3154
WifiPhyState
expectedStateBeforeEnd = WifiPhyState::RX,
3155
TrigVectorInfo
error =
NONE
);
3156
3157
/**
3158
* Schedule power measurement related checks.
3159
*
3160
* @param delay the reference delay used to schedule the events
3161
* @param rxPowerNonOfdmaRu1 the received power on the non-OFDMA part of RU1
3162
* @param rxPowerNonOfdmaRu2 the received power on the non-OFDMA part of RU2
3163
* @param rxPowerOfdmaRu1 the received power on RU1
3164
* @param rxPowerOfdmaRu2 the received power on RU2
3165
*/
3166
void
SchedulePowerMeasurementChecks
(
Time
delay,
3167
Watt_u
rxPowerNonOfdmaRu1,
3168
Watt_u
rxPowerNonOfdmaRu2,
3169
Watt_u
rxPowerOfdmaRu1,
3170
Watt_u
rxPowerOfdmaRu2);
3171
/**
3172
* Log scenario description
3173
*
3174
* @param log the scenario description to add to log
3175
*/
3176
void
LogScenario
(std::string log)
const
;
3177
3178
Ptr<OfdmaSpectrumWifiPhy>
m_phyAp
;
///< PHY of AP
3179
Ptr<OfdmaSpectrumWifiPhy>
m_phySta1
;
///< PHY of STA 1
3180
Ptr<OfdmaSpectrumWifiPhy>
m_phySta2
;
///< PHY of STA 2
3181
Ptr<OfdmaSpectrumWifiPhy>
m_phySta3
;
///< PHY of STA 3
3182
3183
std::shared_ptr<OfdmaTestPhyListener>
3184
m_apPhyStateListener
;
///< listener for AP PHY state transitions
3185
3186
Ptr<WaveformGenerator>
m_phyInterferer
;
///< PHY of interferer
3187
3188
uint32_t
m_countRxSuccessFromSta1
;
///< count RX success from STA 1
3189
uint32_t
m_countRxSuccessFromSta2
;
///< count RX success from STA 2
3190
uint32_t
m_countRxFailureFromSta1
;
///< count RX failure from STA 1
3191
uint32_t
m_countRxFailureFromSta2
;
///< count RX failure from STA 2
3192
uint32_t
m_countRxBytesFromSta1
;
///< count RX bytes from STA 1
3193
uint32_t
m_countRxBytesFromSta2
;
///< count RX bytes from STA 2
3194
3195
MHz_u
m_frequency
;
///< frequency
3196
MHz_u
m_channelWidth
;
///< channel width
3197
Time
m_expectedPpduDuration
;
///< expected duration to send MU PPDU
3198
};
3199
3200
TestUlOfdmaPhyTransmission::TestUlOfdmaPhyTransmission
()
3201
:
TestCase
(
"UL-OFDMA PHY test"
),
3202
m_countRxSuccessFromSta1(0),
3203
m_countRxSuccessFromSta2(0),
3204
m_countRxFailureFromSta1(0),
3205
m_countRxFailureFromSta2(0),
3206
m_countRxBytesFromSta1(0),
3207
m_countRxBytesFromSta2(0),
3208
m_frequency(
DEFAULT_FREQUENCY
),
3209
m_channelWidth(
DEFAULT_CHANNEL_WIDTH
),
3210
m_expectedPpduDuration(
NanoSeconds
(271200))
3211
{
3212
}
3213
3214
void
3215
TestUlOfdmaPhyTransmission::SendHeSuPpdu
(uint16_t txStaId,
3216
std::size_t payloadSize,
3217
uint64_t uid,
3218
uint8_t bssColor)
3219
{
3220
NS_LOG_FUNCTION
(
this
<< txStaId << payloadSize << uid << +bssColor);
3221
WifiConstPsduMap
psdus;
3222
3223
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
3224
0,
3225
WIFI_PREAMBLE_HE_SU
,
3226
NanoSeconds
(800),
3227
1,
3228
1,
3229
0,
3230
m_channelWidth
,
3231
false
,
3232
false
,
3233
false
,
3234
bssColor};
3235
3236
auto
pkt =
Create<Packet>
(payloadSize);
3237
WifiMacHeader
hdr;
3238
hdr.
SetType
(
WIFI_MAC_QOSDATA
);
3239
hdr.
SetQosTid
(0);
3240
hdr.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:00"
));
3241
std::ostringstream addr;
3242
addr <<
"00:00:00:00:00:0"
<< txStaId;
3243
hdr.
SetAddr2
(
Mac48Address
(addr.str().c_str()));
3244
hdr.
SetSequenceNumber
(1);
3245
auto
psdu =
Create<WifiPsdu>
(pkt, hdr);
3246
psdus.insert(std::make_pair(
SU_STA_ID
, psdu));
3247
3248
Ptr<OfdmaSpectrumWifiPhy>
phy;
3249
if
(txStaId == 1)
3250
{
3251
phy =
m_phySta1
;
3252
}
3253
else
if
(txStaId == 2)
3254
{
3255
phy =
m_phySta2
;
3256
}
3257
else
if
(txStaId == 3)
3258
{
3259
phy =
m_phySta3
;
3260
}
3261
else
if
(txStaId == 0)
3262
{
3263
phy =
m_phyAp
;
3264
}
3265
phy->SetPpduUid(uid);
3266
phy->Send(psdus, txVector);
3267
}
3268
3269
WifiTxVector
3270
TestUlOfdmaPhyTransmission::GetTxVectorForHeTbPpdu
(uint16_t txStaId,
3271
std::size_t index,
3272
uint8_t bssColor)
const
3273
{
3274
WifiTxVector
txVector{
HePhy::GetHeMcs7
(),
3275
0,
3276
WIFI_PREAMBLE_HE_TB
,
3277
NanoSeconds
(1600),
3278
1,
3279
1,
3280
0,
3281
m_channelWidth
,
3282
false
,
3283
false
,
3284
false
,
3285
bssColor};
3286
3287
auto
ruType =
HeRu::RU_106_TONE
;
3288
if
(
m_channelWidth
==
MHz_u
{20})
3289
{
3290
ruType =
HeRu::RU_106_TONE
;
3291
}
3292
else
if
(
m_channelWidth
==
MHz_u
{40})
3293
{
3294
ruType =
HeRu::RU_242_TONE
;
3295
}
3296
else
if
(
m_channelWidth
==
MHz_u
{80})
3297
{
3298
ruType =
HeRu::RU_484_TONE
;
3299
}
3300
else
if
(
m_channelWidth
==
MHz_u
{160})
3301
{
3302
ruType =
HeRu::RU_996_TONE
;
3303
}
3304
else
3305
{
3306
NS_ASSERT_MSG
(
false
,
"Unsupported channel width"
);
3307
}
3308
3309
auto
primary80MHz =
true
;
3310
if
(
m_channelWidth
==
MHz_u
{160} && index == 2)
3311
{
3312
primary80MHz =
false
;
3313
index = 1;
3314
}
3315
HeRu::RuSpec
ru(ruType, index, primary80MHz);
3316
txVector.SetRu(ru, txStaId);
3317
txVector.SetMode(
HePhy::GetHeMcs7
(), txStaId);
3318
txVector.SetNss(1, txStaId);
3319
return
txVector;
3320
}
3321
3322
void
3323
TestUlOfdmaPhyTransmission::SetTrigVector
(uint8_t bssColor,
TrigVectorInfo
error)
3324
{
3325
auto
channelWidth =
m_channelWidth
;
3326
if
(error ==
CHANNEL_WIDTH
)
3327
{
3328
channelWidth = (channelWidth ==
MHz_u
{160} ?
MHz_u
{20} : channelWidth * 2);
3329
}
3330
3331
WifiTxVector
txVector(
HePhy::GetHeMcs7
(),
3332
0,
3333
WIFI_PREAMBLE_HE_TB
,
3334
NanoSeconds
(1600),
3335
1,
3336
1,
3337
0,
3338
channelWidth,
3339
false
,
3340
false
,
3341
false
,
3342
bssColor);
3343
3344
HeRu::RuType
ruType =
HeRu::RU_106_TONE
;
3345
if
(channelWidth ==
MHz_u
{20})
3346
{
3347
ruType =
HeRu::RU_106_TONE
;
3348
}
3349
else
if
(channelWidth ==
MHz_u
{40})
3350
{
3351
ruType =
HeRu::RU_242_TONE
;
3352
}
3353
else
if
(channelWidth ==
MHz_u
{80})
3354
{
3355
ruType =
HeRu::RU_484_TONE
;
3356
}
3357
else
if
(channelWidth ==
MHz_u
{160})
3358
{
3359
ruType =
HeRu::RU_996_TONE
;
3360
}
3361
else
3362
{
3363
NS_ASSERT_MSG
(
false
,
"Unsupported channel width"
);
3364
}
3365
3366
uint16_t aid1 = (error ==
AID
? 3 : 1);
3367
uint16_t aid2 = (error ==
AID
? 4 : 2);
3368
3369
HeRu::RuSpec
ru1(ruType, 1,
true
);
3370
txVector.
SetRu
(ru1, aid1);
3371
txVector.
SetMode
(
HePhy::GetHeMcs7
(), aid1);
3372
txVector.
SetNss
(1, aid1);
3373
3374
HeRu::RuSpec
ru2(ruType, (channelWidth ==
MHz_u
{160} ? 1 : 2), (channelWidth !=
MHz_u
{160}));
3375
txVector.
SetRu
(ru2, aid2);
3376
txVector.
SetMode
(
HePhy::GetHeMcs7
(), aid2);
3377
txVector.
SetNss
(1, aid2);
3378
3379
uint16_t length;
3380
std::tie(length,
m_expectedPpduDuration
) =
3381
HePhy::ConvertHeTbPpduDurationToLSigLength
(
m_expectedPpduDuration
,
3382
txVector,
3383
m_phyAp
->
GetPhyBand
());
3384
if
(error ==
UL_LENGTH
)
3385
{
3386
++length;
3387
}
3388
txVector.
SetLength
(length);
3389
auto
hePhyAp =
DynamicCast<HePhy>
(
m_phyAp
->
GetLatestPhyEntity
());
3390
hePhyAp->SetTrigVector(txVector,
m_expectedPpduDuration
);
3391
}
3392
3393
void
3394
TestUlOfdmaPhyTransmission::SendHeTbPpdu
(uint16_t txStaId,
3395
std::size_t index,
3396
std::size_t payloadSize,
3397
uint64_t uid,
3398
uint8_t bssColor,
3399
bool
incrementUid)
3400
{
3401
NS_LOG_FUNCTION
(
this
<< txStaId << index << payloadSize << uid << +bssColor << (incrementUid));
3402
WifiConstPsduMap
psdus;
3403
3404
if
(incrementUid)
3405
{
3406
++uid;
3407
}
3408
3409
WifiTxVector
txVector =
GetTxVectorForHeTbPpdu
(txStaId, index, bssColor);
3410
Ptr<Packet>
pkt =
Create<Packet>
(payloadSize);
3411
WifiMacHeader
hdr;
3412
hdr.
SetType
(
WIFI_MAC_QOSDATA
);
3413
hdr.
SetQosTid
(0);
3414
hdr.
SetAddr1
(
Mac48Address
(
"00:00:00:00:00:00"
));
3415
std::ostringstream addr;
3416
addr <<
"00:00:00:00:00:0"
<< txStaId;
3417
hdr.
SetAddr2
(
Mac48Address
(addr.str().c_str()));
3418
hdr.
SetSequenceNumber
(1);
3419
Ptr<WifiPsdu>
psdu =
Create<WifiPsdu>
(pkt, hdr);
3420
psdus.insert(std::make_pair(txStaId, psdu));
3421
3422
Ptr<OfdmaSpectrumWifiPhy>
phy;
3423
if
(txStaId == 1)
3424
{
3425
phy =
m_phySta1
;
3426
}
3427
else
if
(txStaId == 2)
3428
{
3429
phy =
m_phySta2
;
3430
}
3431
else
if
(txStaId == 3)
3432
{
3433
phy =
m_phySta3
;
3434
}
3435
3436
Time
txDuration =
3437
phy->CalculateTxDuration(psdu->GetSize(), txVector, phy->GetPhyBand(), txStaId);
3438
txVector.
SetLength
(
3439
HePhy::ConvertHeTbPpduDurationToLSigLength
(txDuration, txVector, phy->GetPhyBand()).first);
3440
3441
phy->SetPpduUid(uid);
3442
phy->Send(psdus, txVector);
3443
}
3444
3445
void
3446
TestUlOfdmaPhyTransmission::GenerateInterference
(
Ptr<SpectrumValue>
interferencePsd,
Time
duration)
3447
{
3448
NS_LOG_FUNCTION
(
this
<< duration);
3449
m_phyInterferer
->SetTxPowerSpectralDensity(interferencePsd);
3450
m_phyInterferer
->SetPeriod(duration);
3451
m_phyInterferer
->Start();
3452
Simulator::Schedule
(duration, &
TestUlOfdmaPhyTransmission::StopInterference
,
this
);
3453
}
3454
3455
void
3456
TestUlOfdmaPhyTransmission::StopInterference
()
3457
{
3458
m_phyInterferer
->Stop();
3459
}
3460
3461
TestUlOfdmaPhyTransmission::~TestUlOfdmaPhyTransmission
()
3462
{
3463
}
3464
3465
void
3466
TestUlOfdmaPhyTransmission::RxSuccess
(
Ptr<const WifiPsdu>
psdu,
3467
RxSignalInfo
rxSignalInfo,
3468
const
WifiTxVector
& txVector,
3469
const
std::vector<bool>&
/*statusPerMpdu*/
)
3470
{
3471
NS_LOG_FUNCTION
(
this
<< *psdu << psdu->GetAddr2() << rxSignalInfo << txVector);
3472
if
(psdu->GetAddr2() ==
Mac48Address
(
"00:00:00:00:00:01"
))
3473
{
3474
m_countRxSuccessFromSta1
++;
3475
m_countRxBytesFromSta1
+= (psdu->GetSize() - 30);
3476
}
3477
else
if
(psdu->GetAddr2() ==
Mac48Address
(
"00:00:00:00:00:02"
))
3478
{
3479
m_countRxSuccessFromSta2
++;
3480
m_countRxBytesFromSta2
+= (psdu->GetSize() - 30);
3481
}
3482
}
3483
3484
void
3485
TestUlOfdmaPhyTransmission::RxFailure
(
Ptr<const WifiPsdu>
psdu)
3486
{
3487
NS_LOG_FUNCTION
(
this
<< *psdu << psdu->GetAddr2());
3488
if
(psdu->GetAddr2() ==
Mac48Address
(
"00:00:00:00:00:01"
))
3489
{
3490
m_countRxFailureFromSta1
++;
3491
}
3492
else
if
(psdu->GetAddr2() ==
Mac48Address
(
"00:00:00:00:00:02"
))
3493
{
3494
m_countRxFailureFromSta2
++;
3495
}
3496
}
3497
3498
void
3499
TestUlOfdmaPhyTransmission::CheckRxFromSta1
(
uint32_t
expectedSuccess,
3500
uint32_t
expectedFailures,
3501
uint32_t
expectedBytes)
3502
{
3503
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessFromSta1
,
3504
expectedSuccess,
3505
"The number of successfully received packets from STA 1 is not correct!"
);
3506
NS_TEST_ASSERT_MSG_EQ
(
3507
m_countRxFailureFromSta1
,
3508
expectedFailures,
3509
"The number of unsuccessfuly received packets from STA 1 is not correct!"
);
3510
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesFromSta1
,
3511
expectedBytes,
3512
"The number of bytes received from STA 1 is not correct!"
);
3513
}
3514
3515
void
3516
TestUlOfdmaPhyTransmission::CheckRxFromSta2
(
uint32_t
expectedSuccess,
3517
uint32_t
expectedFailures,
3518
uint32_t
expectedBytes)
3519
{
3520
NS_TEST_ASSERT_MSG_EQ
(
m_countRxSuccessFromSta2
,
3521
expectedSuccess,
3522
"The number of successfully received packets from STA 2 is not correct!"
);
3523
NS_TEST_ASSERT_MSG_EQ
(
3524
m_countRxFailureFromSta2
,
3525
expectedFailures,
3526
"The number of unsuccessfuly received packets from STA 2 is not correct!"
);
3527
NS_TEST_ASSERT_MSG_EQ
(
m_countRxBytesFromSta2
,
3528
expectedBytes,
3529
"The number of bytes received from STA 2 is not correct!"
);
3530
}
3531
3532
void
3533
TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
3534
WifiSpectrumBandInfo
band,
3535
Watt_u
expectedRxPower)
3536
{
3537
auto
event
= phy->GetCurrentEvent();
3538
NS_ASSERT
(event);
3539
auto
rxPower =
event
->GetRxPower(band);
3540
NS_LOG_FUNCTION
(
this
<< band << expectedRxPower << rxPower);
3541
// Since there is out of band emission due to spectrum mask, the tolerance cannot be very low
3542
NS_TEST_ASSERT_MSG_EQ_TOL
(rxPower,
3543
expectedRxPower,
3544
Watt_u
{5e-3},
3545
"RX power "
<< rxPower <<
" over ("
<< band
3546
<<
") does not match expected power "
<< expectedRxPower
3547
<<
" at "
<<
Simulator::Now
());
3548
}
3549
3550
void
3551
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
3552
WifiSpectrumBandInfo
band,
3553
Watt_u
expectedRxPower)
3554
{
3555
/**
3556
* The current event cannot be used since it points to the preamble part of the HE TB PPDU.
3557
* We will have to check if the expected power is indeed the max power returning a positive
3558
* duration when calling GetEnergyDuration.
3559
*/
3560
NS_LOG_FUNCTION
(
this
<< band << expectedRxPower);
3561
Watt_u
step{5e-3};
3562
if
(expectedRxPower >
Watt_u
{0.0})
3563
{
3564
NS_TEST_ASSERT_MSG_EQ
(
3565
phy->GetEnergyDuration(expectedRxPower - step, band).IsStrictlyPositive(),
3566
true
,
3567
"At least "
<< expectedRxPower <<
" W expected for OFDMA part over ("
<< band <<
") at "
3568
<<
Simulator::Now
());
3569
NS_TEST_ASSERT_MSG_EQ
(
3570
phy->GetEnergyDuration(expectedRxPower + step, band).IsStrictlyPositive(),
3571
false
,
3572
"At most "
<< expectedRxPower <<
" W expected for OFDMA part over ("
<< band <<
") at "
3573
<<
Simulator::Now
());
3574
}
3575
else
3576
{
3577
NS_TEST_ASSERT_MSG_EQ
(
3578
phy->GetEnergyDuration(expectedRxPower + step, band).IsStrictlyPositive(),
3579
false
,
3580
"At most "
<< expectedRxPower <<
" W expected for OFDMA part over ("
<< band <<
") at "
3581
<<
Simulator::Now
());
3582
}
3583
}
3584
3585
void
3586
TestUlOfdmaPhyTransmission::VerifyEventsCleared
()
3587
{
3588
NS_TEST_ASSERT_MSG_EQ
(
m_phyAp
->
GetCurrentEvent
(),
3589
nullptr
,
3590
"m_currentEvent for AP was not cleared"
);
3591
NS_TEST_ASSERT_MSG_EQ
(
m_phySta1
->
GetCurrentEvent
(),
3592
nullptr
,
3593
"m_currentEvent for STA 1 was not cleared"
);
3594
NS_TEST_ASSERT_MSG_EQ
(
m_phySta2
->
GetCurrentEvent
(),
3595
nullptr
,
3596
"m_currentEvent for STA 2 was not cleared"
);
3597
}
3598
3599
void
3600
TestUlOfdmaPhyTransmission::CheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
WifiPhyState
expectedState)
3601
{
3602
// This is needed to make sure PHY state will be checked as the last event if a state change
3603
// occurred at the exact same time as the check
3604
Simulator::ScheduleNow
(&
TestUlOfdmaPhyTransmission::DoCheckPhyState
,
this
, phy, expectedState);
3605
}
3606
3607
void
3608
TestUlOfdmaPhyTransmission::DoCheckPhyState
(
Ptr<OfdmaSpectrumWifiPhy>
phy,
3609
WifiPhyState
expectedState)
3610
{
3611
WifiPhyState
currentState;
3612
PointerValue
ptr;
3613
phy->GetAttribute(
"State"
, ptr);
3614
Ptr<WifiPhyStateHelper>
state =
DynamicCast<WifiPhyStateHelper>
(ptr.
Get
<
WifiPhyStateHelper
>());
3615
currentState = state->GetState();
3616
NS_LOG_FUNCTION
(
this
<< currentState);
3617
NS_TEST_ASSERT_MSG_EQ
(currentState,
3618
expectedState,
3619
"PHY State "
<< currentState <<
" does not match expected state "
3620
<< expectedState <<
" at "
<<
Simulator::Now
());
3621
}
3622
3623
void
3624
TestUlOfdmaPhyTransmission::CheckApRxStart
(
uint32_t
expectedNotifications,
3625
Time
expectedLastNotification)
3626
{
3627
NS_TEST_ASSERT_MSG_EQ
(
m_apPhyStateListener
->
GetNumRxStartNotifications
(),
3628
expectedNotifications,
3629
"Number of RX start notifications "
3630
<<
m_apPhyStateListener
->
GetNumRxStartNotifications
()
3631
<<
" does not match expected count "
<< expectedNotifications
3632
<<
" for AP at "
<<
Simulator::Now
());
3633
NS_TEST_ASSERT_MSG_EQ
(
m_apPhyStateListener
->
GetLastRxStartNotification
(),
3634
expectedLastNotification,
3635
"Last time RX start notification has been received "
3636
<<
m_apPhyStateListener
->
GetLastRxStartNotification
()
3637
<<
" does not match expected time "
<< expectedLastNotification
3638
<<
" for AP at "
<<
Simulator::Now
());
3639
}
3640
3641
void
3642
TestUlOfdmaPhyTransmission::CheckApRxEnd
(
uint32_t
expectedNotifications,
3643
Time
expectedLastNotification,
3644
bool
expectedSuccess)
3645
{
3646
NS_TEST_ASSERT_MSG_EQ
(
m_apPhyStateListener
->
GetNumRxEndNotifications
(),
3647
expectedNotifications,
3648
"Number of RX end notifications "
3649
<<
m_apPhyStateListener
->
GetNumRxEndNotifications
()
3650
<<
" does not match expected count "
<< expectedNotifications
3651
<<
" for AP at "
<<
Simulator::Now
());
3652
NS_TEST_ASSERT_MSG_EQ
(
m_apPhyStateListener
->
GetLastRxEndNotification
(),
3653
expectedLastNotification,
3654
"Last time RX end notification has been received "
3655
<<
m_apPhyStateListener
->
GetLastRxEndNotification
()
3656
<<
" does not match expected time "
<< expectedLastNotification
3657
<<
" for AP at "
<<
Simulator::Now
());
3658
NS_TEST_ASSERT_MSG_EQ
(
m_apPhyStateListener
->
IsLastRxSuccess
(),
3659
expectedSuccess,
3660
"Last time RX end notification indicated a "
3661
<< (
m_apPhyStateListener
->
IsLastRxSuccess
() ?
"success"
:
"failure"
)
3662
<<
" but expected a "
<< (expectedSuccess ?
"success"
:
"failure"
)
3663
<<
" for AP at "
<<
Simulator::Now
());
3664
}
3665
3666
void
3667
TestUlOfdmaPhyTransmission::Reset
()
3668
{
3669
m_countRxSuccessFromSta1
= 0;
3670
m_countRxSuccessFromSta2
= 0;
3671
m_countRxFailureFromSta1
= 0;
3672
m_countRxFailureFromSta2
= 0;
3673
m_countRxBytesFromSta1
= 0;
3674
m_countRxBytesFromSta2
= 0;
3675
m_phySta1
->
SetPpduUid
(0);
3676
m_phySta1
->
SetTriggerFrameUid
(0);
3677
m_phySta2
->
SetTriggerFrameUid
(0);
3678
SetBssColor
(
m_phyAp
, 0);
3679
m_apPhyStateListener
->
Reset
();
3680
}
3681
3682
void
3683
TestUlOfdmaPhyTransmission::SetBssColor
(
Ptr<WifiPhy>
phy, uint8_t bssColor)
3684
{
3685
Ptr<WifiNetDevice>
device =
DynamicCast<WifiNetDevice>
(phy->GetDevice());
3686
Ptr<HeConfiguration>
heConfiguration = device->GetHeConfiguration();
3687
heConfiguration->SetAttribute(
"BssColor"
,
UintegerValue
(bssColor));
3688
}
3689
3690
void
3691
TestUlOfdmaPhyTransmission::SetPsdLimit
(
Ptr<WifiPhy>
phy,
dBm_per_MHz_u
psdLimit)
3692
{
3693
NS_LOG_FUNCTION
(
this
<< phy << psdLimit);
3694
phy->SetAttribute(
"PowerDensityLimit"
,
DoubleValue
(psdLimit));
3695
}
3696
3697
void
3698
TestUlOfdmaPhyTransmission::DoSetup
()
3699
{
3700
Ptr<MultiModelSpectrumChannel>
spectrumChannel =
CreateObject<MultiModelSpectrumChannel>
();
3701
Ptr<FriisPropagationLossModel>
lossModel =
CreateObject<FriisPropagationLossModel>
();
3702
lossModel->SetFrequency(
m_frequency
);
3703
spectrumChannel->AddPropagationLossModel(lossModel);
3704
Ptr<ConstantSpeedPropagationDelayModel>
delayModel =
3705
CreateObject<ConstantSpeedPropagationDelayModel>
();
3706
spectrumChannel->SetPropagationDelayModel(delayModel);
3707
3708
Ptr<ThresholdPreambleDetectionModel>
preambleDetectionModel =
3709
CreateObject<ThresholdPreambleDetectionModel>
();
3710
preambleDetectionModel->SetAttribute(
3711
"MinimumRssi"
,
3712
DoubleValue
(
3713
-8));
// to ensure that transmission in neighboring channel is ignored (16 dBm baseline)
3714
preambleDetectionModel->SetAttribute(
"Threshold"
,
DoubleValue
(-100));
// no limit on SNR
3715
3716
Ptr<Node>
apNode =
CreateObject<Node>
();
3717
Ptr<WifiNetDevice>
apDev =
CreateObject<WifiNetDevice>
();
3718
apDev->SetStandard(
WIFI_STANDARD_80211ax
);
3719
auto
apMac =
CreateObjectWithAttributes<ApWifiMac>
(
3720
"Txop"
,
3721
PointerValue
(
CreateObjectWithAttributes<Txop>
(
"AcIndex"
,
StringValue
(
"AC_BE_NQOS"
))));
3722
apMac->SetAttribute(
"BeaconGeneration"
,
BooleanValue
(
false
));
3723
apDev->SetMac(apMac);
3724
m_phyAp
=
CreateObject<OfdmaSpectrumWifiPhy>
(0);
3725
Ptr<HeConfiguration>
heConfiguration =
CreateObject<HeConfiguration>
();
3726
apDev->SetHeConfiguration(heConfiguration);
3727
Ptr<InterferenceHelper>
apInterferenceHelper =
CreateObject<InterferenceHelper>
();
3728
m_phyAp
->
SetInterferenceHelper
(apInterferenceHelper);
3729
Ptr<ErrorRateModel>
apErrorModel =
CreateObject<NistErrorRateModel>
();
3730
m_phyAp
->
SetErrorRateModel
(apErrorModel);
3731
m_phyAp
->
SetDevice
(apDev);
3732
m_phyAp
->
AddChannel
(spectrumChannel);
3733
m_phyAp
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
3734
m_phyAp
->
SetReceiveOkCallback
(
MakeCallback
(&
TestUlOfdmaPhyTransmission::RxSuccess
,
this
));
3735
m_phyAp
->
SetReceiveErrorCallback
(
MakeCallback
(&
TestUlOfdmaPhyTransmission::RxFailure
,
this
));
3736
m_phyAp
->
SetPreambleDetectionModel
(preambleDetectionModel);
3737
Ptr<ConstantPositionMobilityModel>
apMobility =
CreateObject<ConstantPositionMobilityModel>
();
3738
m_phyAp
->
SetMobility
(apMobility);
3739
m_apPhyStateListener
= std::make_unique<OfdmaTestPhyListener>();
3740
m_phyAp
->
RegisterListener
(
m_apPhyStateListener
);
3741
apDev->SetPhy(
m_phyAp
);
3742
apMac->SetWifiPhys({
m_phyAp
});
3743
apNode->AggregateObject(apMobility);
3744
apNode->AddDevice(apDev);
3745
3746
Ptr<Node>
sta1Node =
CreateObject<Node>
();
3747
Ptr<WifiNetDevice>
sta1Dev =
CreateObject<WifiNetDevice>
();
3748
sta1Dev->SetStandard(
WIFI_STANDARD_80211ax
);
3749
sta1Dev->SetHeConfiguration(
CreateObject<HeConfiguration>
());
3750
m_phySta1
=
CreateObject<OfdmaSpectrumWifiPhy>
(1);
3751
Ptr<InterferenceHelper>
sta1InterferenceHelper =
CreateObject<InterferenceHelper>
();
3752
m_phySta1
->
SetInterferenceHelper
(sta1InterferenceHelper);
3753
Ptr<ErrorRateModel>
sta1ErrorModel =
CreateObject<NistErrorRateModel>
();
3754
m_phySta1
->
SetErrorRateModel
(sta1ErrorModel);
3755
m_phySta1
->
SetDevice
(sta1Dev);
3756
m_phySta1
->
AddChannel
(spectrumChannel);
3757
m_phySta1
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
3758
m_phySta1
->
SetPreambleDetectionModel
(preambleDetectionModel);
3759
Ptr<ConstantPositionMobilityModel>
sta1Mobility =
CreateObject<ConstantPositionMobilityModel>
();
3760
m_phySta1
->
SetMobility
(sta1Mobility);
3761
sta1Dev->SetPhy(
m_phySta1
);
3762
sta1Node->AggregateObject(sta1Mobility);
3763
sta1Node->AddDevice(sta1Dev);
3764
3765
Ptr<Node>
sta2Node =
CreateObject<Node>
();
3766
Ptr<WifiNetDevice>
sta2Dev =
CreateObject<WifiNetDevice>
();
3767
sta2Dev->SetStandard(
WIFI_STANDARD_80211ax
);
3768
sta2Dev->SetHeConfiguration(
CreateObject<HeConfiguration>
());
3769
m_phySta2
=
CreateObject<OfdmaSpectrumWifiPhy>
(2);
3770
Ptr<InterferenceHelper>
sta2InterferenceHelper =
CreateObject<InterferenceHelper>
();
3771
m_phySta2
->
SetInterferenceHelper
(sta2InterferenceHelper);
3772
Ptr<ErrorRateModel>
sta2ErrorModel =
CreateObject<NistErrorRateModel>
();
3773
m_phySta2
->
SetErrorRateModel
(sta2ErrorModel);
3774
m_phySta2
->
SetDevice
(sta2Dev);
3775
m_phySta2
->
AddChannel
(spectrumChannel);
3776
m_phySta2
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
3777
m_phySta2
->
SetPreambleDetectionModel
(preambleDetectionModel);
3778
Ptr<ConstantPositionMobilityModel>
sta2Mobility =
CreateObject<ConstantPositionMobilityModel>
();
3779
m_phySta2
->
SetMobility
(sta2Mobility);
3780
sta2Dev->SetPhy(
m_phySta2
);
3781
sta2Node->AggregateObject(sta2Mobility);
3782
sta2Node->AddDevice(sta2Dev);
3783
3784
Ptr<Node>
sta3Node =
CreateObject<Node>
();
3785
Ptr<WifiNetDevice>
sta3Dev =
CreateObject<WifiNetDevice>
();
3786
sta3Dev->SetStandard(
WIFI_STANDARD_80211ax
);
3787
sta3Dev->SetHeConfiguration(
CreateObject<HeConfiguration>
());
3788
m_phySta3
=
CreateObject<OfdmaSpectrumWifiPhy>
(3);
3789
Ptr<InterferenceHelper>
sta3InterferenceHelper =
CreateObject<InterferenceHelper>
();
3790
m_phySta3
->
SetInterferenceHelper
(sta3InterferenceHelper);
3791
Ptr<ErrorRateModel>
sta3ErrorModel =
CreateObject<NistErrorRateModel>
();
3792
m_phySta3
->
SetErrorRateModel
(sta3ErrorModel);
3793
m_phySta3
->
SetDevice
(sta3Dev);
3794
m_phySta3
->
AddChannel
(spectrumChannel);
3795
m_phySta3
->
ConfigureStandard
(
WIFI_STANDARD_80211ax
);
3796
m_phySta3
->
SetPreambleDetectionModel
(preambleDetectionModel);
3797
Ptr<ConstantPositionMobilityModel>
sta3Mobility =
CreateObject<ConstantPositionMobilityModel>
();
3798
m_phySta3
->
SetMobility
(sta3Mobility);
3799
sta3Dev->SetPhy(
m_phySta3
);
3800
sta3Node->AggregateObject(sta3Mobility);
3801
sta3Node->AddDevice(sta3Dev);
3802
3803
Ptr<Node>
interfererNode =
CreateObject<Node>
();
3804
Ptr<NonCommunicatingNetDevice>
interfererDev =
CreateObject<NonCommunicatingNetDevice>
();
3805
m_phyInterferer
=
CreateObject<WaveformGenerator>
();
3806
m_phyInterferer
->SetDevice(interfererDev);
3807
m_phyInterferer
->SetChannel(spectrumChannel);
3808
m_phyInterferer
->SetDutyCycle(1);
3809
interfererNode->AddDevice(interfererDev);
3810
3811
// Configure power attributes of all wifi devices
3812
std::list<Ptr<WifiPhy>> phys{
m_phyAp
,
m_phySta1
,
m_phySta2
,
m_phySta3
};
3813
for
(
auto
& phy : phys)
3814
{
3815
phy->SetAttribute(
"TxGain"
,
DoubleValue
(1.0));
3816
phy->SetAttribute(
"TxPowerStart"
,
DoubleValue
(16.0));
3817
phy->SetAttribute(
"TxPowerEnd"
,
DoubleValue
(16.0));
3818
phy->SetAttribute(
"PowerDensityLimit"
,
DoubleValue
(100.0));
// no impact by default
3819
phy->SetAttribute(
"RxGain"
,
DoubleValue
(2.0));
3820
// test assumes no rejection power for simplicity
3821
phy->SetAttribute(
"TxMaskInnerBandMinimumRejection"
,
DoubleValue
(-100.0));
3822
phy->SetAttribute(
"TxMaskOuterBandMinimumRejection"
,
DoubleValue
(-100.0));
3823
phy->SetAttribute(
"TxMaskOuterBandMaximumRejection"
,
DoubleValue
(-100.0));
3824
}
3825
}
3826
3827
void
3828
TestUlOfdmaPhyTransmission::DoTeardown
()
3829
{
3830
m_phyAp
->
Dispose
();
3831
m_phyAp
=
nullptr
;
3832
m_phySta1
->
Dispose
();
3833
m_phySta1
=
nullptr
;
3834
m_phySta2
->
Dispose
();
3835
m_phySta2
=
nullptr
;
3836
m_phySta3
->
Dispose
();
3837
m_phySta3
=
nullptr
;
3838
m_phyInterferer
->
Dispose
();
3839
m_phyInterferer
=
nullptr
;
3840
}
3841
3842
void
3843
TestUlOfdmaPhyTransmission::LogScenario
(std::string log)
const
3844
{
3845
NS_LOG_INFO
(log);
3846
}
3847
3848
void
3849
TestUlOfdmaPhyTransmission::ScheduleTest
(
Time
delay,
3850
bool
solicited,
3851
WifiPhyState
expectedStateAtEnd,
3852
uint32_t
expectedSuccessFromSta1,
3853
uint32_t
expectedFailuresFromSta1,
3854
uint32_t
expectedBytesFromSta1,
3855
uint32_t
expectedSuccessFromSta2,
3856
uint32_t
expectedFailuresFromSta2,
3857
uint32_t
expectedBytesFromSta2,
3858
bool
scheduleTxSta1,
3859
Time
ulTimeDifference,
3860
WifiPhyState
expectedStateBeforeEnd,
3861
TrigVectorInfo
error)
3862
{
3863
static
uint64_t uid = 0;
3864
3865
// AP sends an SU packet preceding HE TB PPDUs
3866
Simulator::Schedule
(delay -
MilliSeconds
(10),
3867
&
TestUlOfdmaPhyTransmission::SendHeSuPpdu
,
3868
this
,
3869
0,
3870
50,
3871
++uid,
3872
0);
3873
if
(!solicited)
3874
{
3875
// UID of TB PPDUs will be different than the one of the preceding frame
3876
++uid;
3877
}
3878
else
3879
{
3880
Simulator::Schedule
(delay, &
TestUlOfdmaPhyTransmission::SetTrigVector
,
this
, 0, error);
3881
}
3882
// STA1 and STA2 send MU UL PPDUs addressed to AP
3883
Simulator::Schedule
(delay -
MilliSeconds
(1),
3884
&
OfdmaTestPhyListener::Reset
,
3885
m_apPhyStateListener
.get());
3886
if
(scheduleTxSta1)
3887
{
3888
Simulator::Schedule
(delay,
3889
&
TestUlOfdmaPhyTransmission::SendHeTbPpdu
,
3890
this
,
3891
1,
3892
1,
3893
1000,
3894
uid,
3895
0,
3896
false
);
3897
}
3898
Simulator::Schedule
(delay + ulTimeDifference,
3899
&
TestUlOfdmaPhyTransmission::SendHeTbPpdu
,
3900
this
,
3901
2,
3902
2,
3903
1001,
3904
uid,
3905
0,
3906
false
);
3907
3908
// Verify it takes m_expectedPpduDuration to transmit the PPDUs
3909
Simulator::Schedule
(delay +
m_expectedPpduDuration
-
NanoSeconds
(1),
3910
&
TestUlOfdmaPhyTransmission::CheckPhyState
,
3911
this
,
3912
m_phyAp
,
3913
expectedStateBeforeEnd);
3914
Simulator::Schedule
(delay +
m_expectedPpduDuration
+ ulTimeDifference,
3915
&
TestUlOfdmaPhyTransmission::CheckPhyState
,
3916
this
,
3917
m_phyAp
,
3918
expectedStateAtEnd);
3919
// TODO: add checks on TX stop for STAs
3920
3921
if
(expectedSuccessFromSta1 + expectedFailuresFromSta1 + expectedSuccessFromSta2 +
3922
expectedFailuresFromSta2 >
3923
0)
3924
{
3925
// RxEndOk if at least one HE TB PPDU has been successfully received, RxEndError otherwise
3926
const
bool
isSuccess = (expectedSuccessFromSta1 > 0) || (expectedSuccessFromSta2 > 0);
3927
// The expected time at which the reception is started corresponds to the time at which the
3928
// test is started, plus the time to transmit the PHY preamble and the PHY headers.
3929
const
Time
expectedPayloadStart = delay +
MicroSeconds
(48);
3930
// The expected time at which the reception is terminated corresponds to the time at which
3931
// the test is started, plus the time to transmit the PPDU, plus the delay between the first
3932
// received HE TB PPDU and the last received HE TB PPDU.
3933
const
Time
expectedPayloadEnd = delay +
m_expectedPpduDuration
+ ulTimeDifference;
3934
// At the end of the transmission, verify that a single RX start notification shall have
3935
// been notified when the reception of the first HE RB PPDU starts.
3936
Simulator::Schedule
(expectedPayloadEnd,
3937
&
TestUlOfdmaPhyTransmission::CheckApRxStart
,
3938
this
,
3939
1,
3940
Simulator::Now
() + expectedPayloadStart);
3941
// After the reception (hence we add 1ns to expectedPayloadEnd), a single RX end
3942
// notification shall have been notified when the reception of the last HE RB PPDU ends
3943
Simulator::Schedule
(expectedPayloadEnd +
NanoSeconds
(1),
3944
&
TestUlOfdmaPhyTransmission::CheckApRxEnd
,
3945
this
,
3946
1,
3947
Simulator::Now
() + expectedPayloadEnd,
3948
isSuccess);
3949
}
3950
3951
delay +=
MilliSeconds
(100);
3952
// Check reception state from STA 1
3953
Simulator::Schedule
(delay,
3954
&
TestUlOfdmaPhyTransmission::CheckRxFromSta1
,
3955
this
,
3956
expectedSuccessFromSta1,
3957
expectedFailuresFromSta1,
3958
expectedBytesFromSta1);
3959
// Check reception state from STA 2
3960
Simulator::Schedule
(delay,
3961
&
TestUlOfdmaPhyTransmission::CheckRxFromSta2
,
3962
this
,
3963
expectedSuccessFromSta2,
3964
expectedFailuresFromSta2,
3965
expectedBytesFromSta2);
3966
// Verify events data have been cleared
3967
Simulator::Schedule
(delay, &
TestUlOfdmaPhyTransmission::VerifyEventsCleared
,
this
);
3968
3969
delay +=
MilliSeconds
(100);
3970
Simulator::Schedule
(delay, &
TestUlOfdmaPhyTransmission::Reset
,
this
);
3971
}
3972
3973
void
3974
TestUlOfdmaPhyTransmission::SchedulePowerMeasurementChecks
(
Time
delay,
3975
Watt_u
rxPowerNonOfdmaRu1,
3976
Watt_u
rxPowerNonOfdmaRu2,
3977
Watt_u
rxPowerOfdmaRu1,
3978
Watt_u
rxPowerOfdmaRu2)
3979
{
3980
const
auto
detectionDuration =
WifiPhy::GetPreambleDetectionDuration
();
3981
const
auto
txVectorSta1 =
GetTxVectorForHeTbPpdu
(1, 1, 0);
3982
const
auto
txVectorSta2 =
GetTxVectorForHeTbPpdu
(2, 2, 0);
3983
const
auto
hePhy =
m_phyAp
->
GetHePhy
();
3984
const
auto
nonOfdmaDuration = hePhy->CalculateNonHeDurationForHeTb(txVectorSta2);
3985
NS_ASSERT
(nonOfdmaDuration == hePhy->CalculateNonHeDurationForHeTb(txVectorSta1));
3986
3987
std::vector<Watt_u> rxPowerNonOfdma{rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2};
3988
std::vector<WifiSpectrumBandInfo> nonOfdmaBand{hePhy->GetNonOfdmaBand(txVectorSta1, 1),
3989
hePhy->GetNonOfdmaBand(txVectorSta2, 2)};
3990
std::vector<Watt_u> rxPowerOfdma{rxPowerOfdmaRu1, rxPowerOfdmaRu2};
3991
std::vector<WifiSpectrumBandInfo> ofdmaBand{hePhy->GetRuBandForRx(txVectorSta1, 1),
3992
hePhy->GetRuBandForRx(txVectorSta2, 2)};
3993
3994
for
(uint8_t i = 0; i < 2; ++i)
3995
{
3996
/**
3997
* Perform checks at AP
3998
*/
3999
// Check received power on non-OFDMA portion
4000
Simulator::Schedule
(
4001
delay + detectionDuration +
4002
NanoSeconds
(1),
// just after beginning of portion (once event is stored)
4003
&
TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower
,
4004
this
,
4005
m_phyAp
,
4006
nonOfdmaBand[i],
4007
rxPowerNonOfdma[i]);
4008
Simulator::Schedule
(delay + nonOfdmaDuration -
NanoSeconds
(1),
// just before end of portion
4009
&
TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower
,
4010
this
,
4011
m_phyAp
,
4012
nonOfdmaBand[i],
4013
rxPowerNonOfdma[i]);
4014
// Check received power on OFDMA portion
4015
Simulator::Schedule
(delay + nonOfdmaDuration +
4016
NanoSeconds
(1),
// just after beginning of portion
4017
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4018
this
,
4019
m_phyAp
,
4020
ofdmaBand[i],
4021
rxPowerOfdma[i]);
4022
Simulator::Schedule
(delay +
m_expectedPpduDuration
-
4023
NanoSeconds
(1),
// just before end of portion
4024
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4025
this
,
4026
m_phyAp
,
4027
ofdmaBand[i],
4028
rxPowerOfdma[i]);
4029
4030
/**
4031
* Perform checks for non-transmitting STA (STA 3).
4032
* Cannot use CheckNonOfdmaRxPower method since current event may be reset if
4033
* preamble not detected (e.g. not on primary).
4034
*/
4035
// Check received power on non-OFDMA portion
4036
Simulator::Schedule
(
4037
delay + detectionDuration +
4038
NanoSeconds
(1),
// just after beginning of portion (once event is stored)
4039
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4040
this
,
4041
m_phySta3
,
4042
nonOfdmaBand[i],
4043
rxPowerNonOfdma[i]);
4044
Simulator::Schedule
(delay + nonOfdmaDuration -
NanoSeconds
(1),
// just before end of portion
4045
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4046
this
,
4047
m_phySta3
,
4048
nonOfdmaBand[i],
4049
rxPowerNonOfdma[i]);
4050
// Check received power on OFDMA portion
4051
Simulator::Schedule
(delay + nonOfdmaDuration +
4052
NanoSeconds
(1),
// just after beginning of portion
4053
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4054
this
,
4055
m_phySta3
,
4056
ofdmaBand[i],
4057
rxPowerOfdma[i]);
4058
Simulator::Schedule
(delay +
m_expectedPpduDuration
-
4059
NanoSeconds
(1),
// just before end of portion
4060
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4061
this
,
4062
m_phySta3
,
4063
ofdmaBand[i],
4064
rxPowerOfdma[i]);
4065
}
4066
4067
if
(rxPowerOfdmaRu1 !=
Watt_u
{0.0})
4068
{
4069
/**
4070
* Perform checks for transmitting STA (STA 2) to ensure it has correctly logged
4071
* power received from other transmitting STA (STA 1).
4072
* Cannot use CheckNonOfdmaRxPower method since current event not set.
4073
*/
4074
const
auto
rxPowerNonOfdmaSta1Only =
4075
(
m_channelWidth
>=
MHz_u
{40})
4076
? rxPowerNonOfdma[0]
4077
: rxPowerNonOfdma[0] / 2;
// both STAs transmit over the same 20 MHz channel
4078
// Check received power on non-OFDMA portion
4079
Simulator::Schedule
(
4080
delay + detectionDuration +
4081
NanoSeconds
(1),
// just after beginning of portion (once event is stored)
4082
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4083
this
,
4084
m_phySta2
,
4085
nonOfdmaBand[0],
4086
rxPowerNonOfdmaSta1Only);
4087
Simulator::Schedule
(delay + nonOfdmaDuration -
NanoSeconds
(1),
// just before end of portion
4088
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4089
this
,
4090
m_phySta2
,
4091
nonOfdmaBand[0],
4092
rxPowerNonOfdmaSta1Only);
4093
// Check received power on OFDMA portion
4094
Simulator::Schedule
(delay + nonOfdmaDuration +
4095
NanoSeconds
(1),
// just after beginning of portion
4096
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4097
this
,
4098
m_phySta2
,
4099
ofdmaBand[0],
4100
rxPowerOfdma[0]);
4101
Simulator::Schedule
(delay +
m_expectedPpduDuration
-
4102
NanoSeconds
(1),
// just before end of portion
4103
&
TestUlOfdmaPhyTransmission::CheckOfdmaRxPower
,
4104
this
,
4105
m_phySta2
,
4106
ofdmaBand[0],
4107
rxPowerOfdma[0]);
4108
}
4109
}
4110
4111
void
4112
TestUlOfdmaPhyTransmission::RunOne
()
4113
{
4114
RngSeedManager::SetSeed
(1);
4115
RngSeedManager::SetRun
(1);
4116
int64_t streamNumber = 0;
4117
m_phyAp
->
AssignStreams
(streamNumber);
4118
m_phySta1
->
AssignStreams
(streamNumber);
4119
m_phySta2
->
AssignStreams
(streamNumber);
4120
m_phySta3
->
AssignStreams
(streamNumber);
4121
4122
auto
channelNum =
WifiPhyOperatingChannel::FindFirst
(0,
4123
m_frequency
,
4124
m_channelWidth
,
4125
WIFI_STANDARD_80211ax
,
4126
WIFI_PHY_BAND_5GHZ
)
4127
->number;
4128
4129
m_phyAp
->
SetOperatingChannel
(
4130
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
4131
m_phySta1
->
SetOperatingChannel
(
4132
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
4133
m_phySta2
->
SetOperatingChannel
(
4134
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
4135
m_phySta3
->
SetOperatingChannel
(
4136
WifiPhy::ChannelTuple
{channelNum,
m_channelWidth
,
WIFI_PHY_BAND_5GHZ
, 0});
4137
4138
Time
delay;
4139
Simulator::Schedule
(delay, &
TestUlOfdmaPhyTransmission::Reset
,
this
);
4140
delay +=
Seconds
(1);
4141
4142
/**
4143
* In all the following tests, 2 HE TB PPDUs of the same UL MU transmission
4144
* are sent on RU 1 for STA 1 and RU 2 for STA 2.
4145
* The difference between solicited and unsolicited lies in that their PPDU
4146
* ID correspond to the one of the immediately preceding HE SU PPDU (thus
4147
* mimicking trigger frame reception).
4148
*/
4149
4150
//---------------------------------------------------------------------------
4151
// Verify that both solicited HE TB PPDUs have been corrected received
4152
Simulator::Schedule
(delay,
4153
&
TestUlOfdmaPhyTransmission::LogScenario
,
4154
this
,
4155
"Reception of solicited HE TB PPDUs"
);
4156
ScheduleTest
(delay,
4157
true
,
4158
WifiPhyState::IDLE,
4159
1,
4160
0,
4161
1000,
// One PSDU of 1000 bytes should have been successfully received from STA 1
4162
1,
4163
0,
4164
1001);
// One PSDU of 1001 bytes should have been successfully received from STA 2
4165
delay +=
Seconds
(1);
4166
4167
//---------------------------------------------------------------------------
4168
// Verify that two solicited HE TB PPDUs with delay (< 400ns) between the two signals have been
4169
// corrected received
4170
Simulator::Schedule
(
4171
delay,
4172
&
TestUlOfdmaPhyTransmission::LogScenario
,
4173
this
,
4174
"Reception of solicited HE TB PPDUs with delay (< 400ns) between the two signals"
);
4175
ScheduleTest
(delay,
4176
true
,
4177
WifiPhyState::IDLE,
4178
1,
4179
0,
4180
1000,
// One PSDU of 1000 bytes should have been successfully received from STA 1
4181
1,
4182
0,
4183
1001,
// One PSDU of 1001 bytes should have been successfully received from STA 2
4184
true
,
4185
NanoSeconds
(100));
4186
delay +=
Seconds
(1);
4187
4188
//---------------------------------------------------------------------------
4189
// Verify that no unsolicited HE TB PPDU is received
4190
Simulator::Schedule
(delay,
4191
&
TestUlOfdmaPhyTransmission::LogScenario
,
4192
this
,
4193
"Dropping of unsolicited HE TB PPDUs"
);
4194
ScheduleTest
(delay,
4195
false
,
4196
WifiPhyState::IDLE,
4197
0,
4198
0,
4199
0,
// PSDU from STA 1 is not received (no TRIGVECTOR)
4200
0,
4201
0,
4202
0,
// PSDU from STA 2 is not received (no TRIGVECTOR)
4203
true
,
4204
Seconds
(0),
4205
WifiPhyState::CCA_BUSY);
4206
delay +=
Seconds
(1);
4207
4208
//---------------------------------------------------------------------------
4209
// Verify that HE TB PPDUs with channel width differing from TRIGVECTOR are discarded
4210
Simulator::Schedule
(delay,
4211
&
TestUlOfdmaPhyTransmission::LogScenario
,
4212
this
,
4213
"Dropping of HE TB PPDUs with channel width differing from TRIGVECTOR"
);
4214
ScheduleTest
(delay,
4215
true
,
4216
WifiPhyState::IDLE,
4217
0,
4218
0,
4219
0,
// PSDU from STA 1 is not received (no TRIGVECTOR)
4220
0,
4221
0,
4222
0,
// PSDU from STA 2 is not received (no TRIGVECTOR)
4223
true
,
4224
Seconds
(0),
4225
WifiPhyState::CCA_BUSY,
4226
CHANNEL_WIDTH
);
4227
delay +=
Seconds
(1);
4228
4229
//---------------------------------------------------------------------------
4230
// Verify that HE TB PPDUs with UL Length differing from TRIGVECTOR are discarded
4231
Simulator::Schedule
(delay,
4232
&
TestUlOfdmaPhyTransmission::LogScenario
,
4233
this
,
4234
"Dropping of HE TB PPDUs with UL Length differing from TRIGVECTOR"
);
4235
ScheduleTest
(delay,
4236
true
,
4237
WifiPhyState::IDLE,
4238
0,
4239
0,
4240
0,
// PSDU from STA 1 is not received (no TRIGVECTOR)
4241
0,
4242
0,
4243
0,
// PSDU from STA 2 is not received (no TRIGVECTOR)
4244
true
,
4245
Seconds
(0),
4246
WifiPhyState::CCA_BUSY,
4247
UL_LENGTH
);
4248
delay +=
Seconds
(1);
4249
4250
//---------------------------------------------------------------------------
4251
// Verify that HE TB PPDUs with AIDs differing from TRIGVECTOR are discarded
4252
Simulator::Schedule
(delay,
4253
&
TestUlOfdmaPhyTransmission::LogScenario
,
4254
this
,
4255
"Dropping of HE TB PPDUs with AIDs differing from TRIGVECTOR"
);
4256
ScheduleTest
(delay,
4257
true
,
4258
WifiPhyState::IDLE,
4259
0,
4260
0,
4261
0,
// PSDU from STA 1 is not received (no TRIGVECTOR)
4262
0,
4263
0,
4264
0,
// PSDU from STA 2 is not received (no TRIGVECTOR)
4265
true
,
4266
Seconds
(0),
4267
WifiPhyState::CCA_BUSY,
4268
AID
);
4269
delay +=
Seconds
(1);
4270
4271
//---------------------------------------------------------------------------
4272
// Generate an interference on RU 1 and verify that only STA 1's solicited HE TB PPDU has been
4273
// impacted
4274
Simulator::Schedule
(
4275
delay,
4276
&
TestUlOfdmaPhyTransmission::LogScenario
,
4277
this
,
4278
"Reception of solicited HE TB PPDUs with interference on RU 1 during PSDU reception"
);
4279
// A strong non-wifi interference is generated on RU 1 during PSDU reception
4280
BandInfo
bandInfo;
4281
bandInfo.
fc
=
MHzToHz
(
m_frequency
- (
m_channelWidth
/ 4));
4282
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(
m_channelWidth
/ 4);
4283
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(
m_channelWidth
/ 4);
4284
Bands
bands;
4285
bands.push_back(bandInfo);
4286
4287
Ptr<SpectrumModel>
SpectrumInterferenceRu1 =
Create<SpectrumModel>
(bands);
4288
Ptr<SpectrumValue>
interferencePsdRu1 =
Create<SpectrumValue>
(SpectrumInterferenceRu1);
4289
Watt_u
interferencePower{0.1};
4290
*interferencePsdRu1 = interferencePower / (
MHzToHz
(
m_channelWidth
/ 2) * 20);
4291
4292
Simulator::Schedule
(delay +
MicroSeconds
(50),
4293
&
TestUlOfdmaPhyTransmission::GenerateInterference
,
4294
this
,
4295
interferencePsdRu1,
4296
MilliSeconds
(100));
4297
ScheduleTest
(
4298
delay,
4299
true
,
4300
WifiPhyState::CCA_BUSY,
// PHY should move to CCA_BUSY instead of IDLE due to the
4301
// interference
4302
0,
4303
1,
4304
0,
// Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
4305
1,
4306
0,
4307
1001);
// One PSDU of 1001 bytes should have been successfully received from STA 2
4308
delay +=
Seconds
(1);
4309
4310
//---------------------------------------------------------------------------
4311
// Generate an interference on RU 2 and verify that only STA 2's solicited HE TB PPDU has been
4312
// impacted
4313
Simulator::Schedule
(
4314
delay,
4315
&
TestUlOfdmaPhyTransmission::LogScenario
,
4316
this
,
4317
"Reception of solicited HE TB PPDUs with interference on RU 2 during PSDU reception"
);
4318
// A strong non-wifi interference is generated on RU 2 during PSDU reception
4319
bandInfo.
fc
=
MHzToHz
(
m_frequency
+ (
m_channelWidth
/ 4));
4320
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(
m_channelWidth
/ 4);
4321
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(
m_channelWidth
/ 4);
4322
bands.clear();
4323
bands.push_back(bandInfo);
4324
4325
Ptr<SpectrumModel>
SpectrumInterferenceRu2 =
Create<SpectrumModel>
(bands);
4326
Ptr<SpectrumValue>
interferencePsdRu2 =
Create<SpectrumValue>
(SpectrumInterferenceRu2);
4327
*interferencePsdRu2 = interferencePower / (
MHzToHz
(
m_channelWidth
/ 2) * 20);
4328
4329
Simulator::Schedule
(delay +
MicroSeconds
(50),
4330
&
TestUlOfdmaPhyTransmission::GenerateInterference
,
4331
this
,
4332
interferencePsdRu2,
4333
MilliSeconds
(100));
4334
ScheduleTest
(delay,
4335
true
,
4336
(
m_channelWidth
>=
MHz_u
{40})
4337
? WifiPhyState::IDLE
4338
: WifiPhyState::CCA_BUSY,
// PHY should move to CCA_BUSY if interference is
4339
// generated in its primary channel
4340
1,
4341
0,
4342
1000,
// One PSDU of 1000 bytes should have been successfully received from STA 1
4343
0,
4344
1,
4345
0);
// Reception of the PSDU from STA 2 should have failed (since interference
4346
// occupies RU 2)
4347
delay +=
Seconds
(1);
4348
4349
//---------------------------------------------------------------------------
4350
// Generate an interference on the full band and verify that both solicited HE TB PPDUs have
4351
// been impacted
4352
Simulator::Schedule
(delay,
4353
&
TestUlOfdmaPhyTransmission::LogScenario
,
4354
this
,
4355
"Reception of solicited HE TB PPDUs with interference on the full band "
4356
"during PSDU reception"
);
4357
// A strong non-wifi interference is generated on the full band during PSDU reception
4358
bandInfo.
fc
=
MHzToHz
(
m_frequency
);
4359
bandInfo.
fl
= bandInfo.
fc
-
MHzToHz
(
m_channelWidth
/ 2);
4360
bandInfo.
fh
= bandInfo.
fc
+
MHzToHz
(
m_channelWidth
/ 2);
4361
bands.clear();
4362
bands.push_back(bandInfo);
4363
4364
Ptr<SpectrumModel>
SpectrumInterferenceAll =
Create<SpectrumModel>
(bands);
4365
Ptr<SpectrumValue>
interferencePsdAll =
Create<SpectrumValue>
(SpectrumInterferenceAll);
4366
*interferencePsdAll = interferencePower / (
MHzToHz
(
m_channelWidth
) * 20);
4367
4368
Simulator::Schedule
(delay +
MicroSeconds
(50),
4369
&
TestUlOfdmaPhyTransmission::GenerateInterference
,
4370
this
,
4371
interferencePsdAll,
4372
MilliSeconds
(100));
4373
ScheduleTest
(
4374
delay,
4375
true
,
4376
WifiPhyState::CCA_BUSY,
// PHY should move to CCA_BUSY instead of IDLE due to the
4377
// interference
4378
0,
4379
1,
4380
0,
// Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
4381
0,
4382
1,
4383
0);
// Reception of the PSDU from STA 2 should have failed (since interference occupies RU
4384
// 2)
4385
delay +=
Seconds
(1);
4386
4387
//---------------------------------------------------------------------------
4388
// Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both
4389
// solicited HE TB PPDUs have been impacted if they are on the same
4390
// 20 MHz channel. Only STA 1's solicited HE TB PPDU is impacted otherwise.
4391
Simulator::Schedule
(delay,
4392
&
TestUlOfdmaPhyTransmission::LogScenario
,
4393
this
,
4394
"Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU "
4395
"1 during PSDU reception"
);
4396
// Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
4397
Simulator::Schedule
(delay +
MicroSeconds
(50),
4398
&
TestUlOfdmaPhyTransmission::SendHeTbPpdu
,
4399
this
,
4400
3,
4401
1,
4402
1002,
4403
1,
4404
0,
4405
false
);
4406
// Expected figures from STA 2
4407
uint32_t
succ;
4408
uint32_t
fail;
4409
uint32_t
bytes;
4410
if
(
m_channelWidth
>
MHz_u
{20})
4411
{
4412
// One PSDU of 1001 bytes should have been successfully received from STA 2 (since
4413
// interference from STA 3 on distinct 20 MHz channel)
4414
succ = 1;
4415
fail = 0;
4416
bytes = 1001;
4417
}
4418
else
4419
{
4420
// Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on
4421
// same 20 MHz channel)
4422
succ = 0;
4423
fail = 1;
4424
bytes = 0;
4425
}
4426
ScheduleTest
(delay,
4427
true
,
4428
WifiPhyState::CCA_BUSY,
// PHY should move to CCA_BUSY instead of IDLE due to the
4429
// interference on measurement channel width
4430
0,
4431
1,
4432
0,
// Reception of the PSDU from STA 1 should have failed (since interference from
4433
// STA 3 on same 20 MHz channel)
4434
succ,
4435
fail,
4436
bytes);
4437
delay +=
Seconds
(1);
4438
4439
//---------------------------------------------------------------------------
4440
// Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both
4441
// solicited HE TB PPDUs have been impacted if they are on the same
4442
// 20 MHz channel. Only STA 2's solicited HE TB PPDU is impacted otherwise.
4443
Simulator::Schedule
(delay,
4444
&
TestUlOfdmaPhyTransmission::LogScenario
,
4445
this
,
4446
"Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU "
4447
"2 during PSDU reception"
);
4448
// Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
4449
Simulator::Schedule
(delay +
MicroSeconds
(50),
4450
&
TestUlOfdmaPhyTransmission::SendHeTbPpdu
,
4451
this
,
4452
3,
4453
2,
4454
1002,
4455
1,
4456
0,
4457
false
);
4458
// Expected figures from STA 1
4459
if
(
m_channelWidth
>
MHz_u
{20})
4460
{
4461
// One PSDU of 1000 bytes should have been successfully received from STA 1 (since
4462
// interference from STA 3 on distinct 20 MHz channel)
4463
succ = 1;
4464
fail = 0;
4465
bytes = 1000;
4466
}
4467
else
4468
{
4469
// Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on
4470
// same 20 MHz channel)
4471
succ = 0;
4472
fail = 1;
4473
bytes = 0;
4474
}
4475
ScheduleTest
(delay,
4476
true
,
4477
(
m_channelWidth
>=
MHz_u
{40})
4478
? WifiPhyState::IDLE
4479
: WifiPhyState::CCA_BUSY,
// PHY should move to CCA_BUSY instead of IDLE if HE
4480
// TB PPDU on primary channel
4481
succ,
4482
fail,
4483
bytes,
4484
0,
4485
1,
4486
0);
// Reception of the PSDU from STA 2 should have failed (since interference from
4487
// STA 3 on same 20 MHz channel)
4488
delay +=
Seconds
(1);
4489
4490
//---------------------------------------------------------------------------
4491
// Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been
4492
// impacted
4493
Simulator::Schedule
(
4494
delay,
4495
&
TestUlOfdmaPhyTransmission::LogScenario
,
4496
this
,
4497
"Reception of solicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window"
);
4498
// One HE SU arrives at AP during the 400ns window
4499
Simulator::Schedule
(delay +
NanoSeconds
(300),
4500
&
TestUlOfdmaPhyTransmission::SendHeSuPpdu
,
4501
this
,
4502
3,
4503
1002,
4504
1,
4505
0);
4506
ScheduleTest
(
4507
delay,
4508
true
,
4509
WifiPhyState::IDLE,
4510
0,
4511
1,
4512
0,
// Reception of the PSDU from STA 1 should have failed (since interference from STA 3)
4513
0,
4514
1,
4515
0);
// Reception of the PSDU from STA 2 should have failed (since interference from STA 3)
4516
delay +=
Seconds
(1);
4517
4518
//---------------------------------------------------------------------------
4519
// Only send a solicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly
4520
// received
4521
Simulator::Schedule
(delay,
4522
&
TestUlOfdmaPhyTransmission::LogScenario
,
4523
this
,
4524
"Reception of solicited HE TB PPDU only on RU 2"
);
4525
// Check that STA3 will correctly set its state to CCA_BUSY if in measurement channel or IDLE
4526
// otherwise
4527
Simulator::Schedule
(delay +
m_expectedPpduDuration
-
NanoSeconds
(1),
4528
&
TestUlOfdmaPhyTransmission::CheckPhyState
,
4529
this
,
4530
m_phySta3
,
4531
(
m_channelWidth
>=
MHz_u
{40})
4532
? WifiPhyState::IDLE
4533
: WifiPhyState::CCA_BUSY);
// PHY should move to CCA_BUSY instead of
4534
// IDLE if HE TB PPDU on primary channel
4535
ScheduleTest
(delay,
4536
true
,
4537
WifiPhyState::IDLE,
4538
0,
4539
0,
4540
0,
// No transmission scheduled for STA 1
4541
1,
4542
0,
4543
1001,
// One PSDU of 1001 bytes should have been successfully received from STA 2
4544
false
,
4545
Seconds
(0),
4546
WifiPhyState::RX);
// Measurement channel is total channel width
4547
delay +=
Seconds
(1);
4548
4549
//---------------------------------------------------------------------------
4550
// Measure the power of a solicited HE TB PPDU from STA 2 on RU 2
4551
Simulator::Schedule
(delay,
4552
&
TestUlOfdmaPhyTransmission::LogScenario
,
4553
this
,
4554
"Measure power for reception of HE TB PPDU only on RU 2"
);
4555
auto
rxPower =
DbmToW
(
4556
dBm_u
{19});
// 16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
4557
SchedulePowerMeasurementChecks
(delay,
4558
(
m_channelWidth
>=
MHz_u
{40}) ?
Watt_u
{0.0} : rxPower,
4559
rxPower,
// power detected on RU1 only if same 20 MHz as RU 2
4560
Watt_u
{0.0},
4561
rxPower);
4562
ScheduleTest
(delay,
4563
true
,
4564
WifiPhyState::IDLE,
4565
0,
4566
0,
4567
0,
// No transmission scheduled for STA 1
4568
1,
4569
0,
4570
1001,
// One PSDU of 1001 bytes should have been successfully received from STA 2
4571
false
,
4572
Seconds
(0),
4573
WifiPhyState::RX);
// Measurement channel is total channel width
4574
delay +=
Seconds
(1);
4575
4576
//---------------------------------------------------------------------------
4577
// Measure the power of a solicited HE TB PPDU from STA 2 on RU 2 with power spectrum density
4578
// limitation enforced
4579
Simulator::Schedule
(
4580
delay,
4581
&
TestUlOfdmaPhyTransmission::LogScenario
,
4582
this
,
4583
"Measure power for reception of HE TB PPDU only on RU 2 with PSD limitation"
);
4584
// Configure PSD limitation at 3 dBm/MHz -> 3+13.0103=16.0103 dBm max for 20 MHz,
4585
// 3+9.0309=12.0309 dBm max for 106-tone RU, no impact for 40 MHz and above
4586
Simulator::Schedule
(delay -
NanoSeconds
(1),
// just before sending HE TB
4587
&
TestUlOfdmaPhyTransmission::SetPsdLimit
,
4588
this
,
4589
m_phySta2
,
4590
dBm_per_MHz_u
{3});
4591
4592
rxPower = (
m_channelWidth
>
MHz_u
{40})
4593
?
DbmToW
(
dBm_u
{19})
4594
:
DbmToW
(
dBm_u
{18.0103});
// 15.0103+1 dBm at STA 2 and +2 at AP for non-OFDMA
4595
// transmitted only on one 20 MHz channel
4596
auto
rxPowerOfdma = rxPower;
4597
if
(
m_channelWidth
<=
MHz_u
{40})
4598
{
4599
rxPowerOfdma =
4600
(
m_channelWidth
==
MHz_u
{20})
4601
?
DbmToW
(
dBm_u
{14.0309})
// 11.0309+1 dBm at STA and +2 at AP if 106-tone RU
4602
:
DbmToW
(
dBm_u
{18.0103});
// 15.0103+1 dBm at STA 2 and +2 at AP if 242-tone RU
4603
}
4604
SchedulePowerMeasurementChecks
(delay,
4605
(
m_channelWidth
>=
MHz_u
{40}) ?
Watt_u
{0.0} : rxPower,
4606
rxPower,
// power detected on RU1 only if same 20 MHz as RU 2
4607
Watt_u
{0.0},
4608
rxPowerOfdma);
4609
4610
// Reset PSD limitation once HE TB has been sent
4611
Simulator::Schedule
(delay +
m_expectedPpduDuration
,
4612
&
TestUlOfdmaPhyTransmission::SetPsdLimit
,
4613
this
,
4614
m_phySta2
,
4615
dBm_per_MHz_u
{100});
4616
ScheduleTest
(delay,
4617
true
,
4618
WifiPhyState::IDLE,
4619
0,
4620
0,
4621
0,
// No transmission scheduled for STA 1
4622
1,
4623
0,
4624
1001,
// One PSDU of 1001 bytes should have been successfully received from STA 2
4625
false
,
4626
Seconds
(0),
4627
WifiPhyState::RX);
// Measurement channel is total channel width
4628
delay +=
Seconds
(1);
4629
4630
//---------------------------------------------------------------------------
4631
// Measure the power of 2 solicited HE TB PPDU from both STAs
4632
Simulator::Schedule
(delay,
4633
&
TestUlOfdmaPhyTransmission::LogScenario
,
4634
this
,
4635
"Measure power for reception of HE TB PPDU on both RUs"
);
4636
rxPower =
DbmToW
(
4637
dBm_u
{19});
// 16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
4638
const
auto
rxPowerNonOfdma =
4639
(
m_channelWidth
>=
MHz_u
{40})
4640
? rxPower
4641
: rxPower * 2;
// both STAs transmit over the same 20 MHz channel
4642
SchedulePowerMeasurementChecks
(delay, rxPowerNonOfdma, rxPowerNonOfdma, rxPower, rxPower);
4643
ScheduleTest
(delay,
4644
true
,
4645
WifiPhyState::IDLE,
4646
1,
4647
0,
4648
1000,
// One PSDU of 1000 bytes should have been successfully received from STA 1
4649
1,
4650
0,
4651
1001);
// One PSDU of 1001 bytes should have been successfully received from STA 2
4652
delay +=
Seconds
(1);
4653
4654
//---------------------------------------------------------------------------
4655
// Verify that an HE TB PPDU from another BSS has been correctly received (no UL MU transmission
4656
// ongoing)
4657
Simulator::Schedule
(delay,
4658
&
TestUlOfdmaPhyTransmission::LogScenario
,
4659
this
,
4660
"Reception of an HE TB PPDU from another BSS"
);
4661
// One HE TB from another BSS (BSS color 2) arrives at AP (BSS color 1)
4662
Simulator::Schedule
(delay, &
TestUlOfdmaPhyTransmission::SetBssColor
,
this
,
m_phyAp
, 1);
4663
Simulator::Schedule
(delay +
MilliSeconds
(100),