21 #include "ns3/dsss-phy.h"
22 #include "ns3/eht-phy.h"
23 #include "ns3/erp-ofdm-phy.h"
24 #include "ns3/he-ru.h"
26 #include "ns3/packet.h"
27 #include "ns3/simulator.h"
29 #include "ns3/wifi-psdu.h"
30 #include "ns3/yans-wifi-phy.h"
49 void DoRun()
override;
65 bool CheckPayloadDuration(uint32_t size,
67 uint16_t channelWidth,
68 uint16_t guardInterval,
85 bool CheckTxDuration(uint32_t size,
87 uint16_t channelWidth,
88 uint16_t guardInterval,
105 static bool CheckMuTxDuration(std::list<uint32_t> sizes,
106 std::list<HeMuUserInfo> userInfos,
107 uint16_t channelWidth,
108 uint16_t guardInterval,
126 static Time CalculateTxDurationUsingList(std::list<uint32_t> sizes,
127 std::list<uint16_t> staIds,
144 uint16_t channelWidth,
145 uint16_t guardInterval,
157 std::list<WifiPhyBand> testedBands;
171 for (
auto& testedBand : testedBands)
179 Time calculatedDuration =
phy->GetPayloadDuration(size, txVector, testedBand);
180 if (calculatedDuration != knownDuration)
182 std::cerr <<
"size=" << size <<
" band=" << testedBand <<
" mode=" << payloadMode
183 <<
" channelWidth=" << channelWidth <<
" guardInterval=" << guardInterval
184 <<
" datarate=" << payloadMode.
GetDataRate(channelWidth, guardInterval, 1)
185 <<
" known=" << knownDuration <<
" calculated=" << calculatedDuration
196 uint16_t channelWidth,
197 uint16_t guardInterval,
209 std::list<WifiPhyBand> testedBands;
223 for (
auto& testedBand : testedBands)
231 Time calculatedDuration =
phy->CalculateTxDuration(size, txVector, testedBand);
232 Time calculatedDurationUsingList =
237 if (calculatedDuration != knownDuration ||
238 calculatedDuration != calculatedDurationUsingList)
240 std::cerr <<
"size=" << size <<
" band=" << testedBand <<
" mode=" << payloadMode
241 <<
" channelWidth=" << +channelWidth <<
" guardInterval=" << guardInterval
242 <<
" datarate=" << payloadMode.
GetDataRate(channelWidth, guardInterval, 1)
243 <<
" preamble=" << preamble <<
" known=" << knownDuration
244 <<
" calculated=" << calculatedDuration
245 <<
" calculatedUsingList=" << calculatedDurationUsingList << std::endl;
254 std::list<HeMuUserInfo> userInfos,
255 uint16_t channelWidth,
256 uint16_t guardInterval,
260 NS_ASSERT(sizes.size() == userInfos.size() && sizes.size() > 1);
262 channelWidth < std::accumulate(
263 std::begin(userInfos),
267 return prevBw + HeRu::GetBandwidth(info.
ru.
GetRuType());
269 "Cannot accommodate all the RUs in the provided band");
281 std::list<uint16_t> staIds;
284 for (
const auto& userInfo : userInfos)
287 staIds.push_back(staId++);
293 std::list<WifiPhyBand> testedBands{
298 for (
auto& testedBand : testedBands)
306 uint32_t longuestSize = 0;
307 auto iterStaId = staIds.begin();
308 for (
auto& size : sizes)
310 Time ppduDurationForSta =
311 phy->CalculateTxDuration(size, txVector, testedBand, *iterStaId);
312 if (ppduDurationForSta > calculatedDuration)
314 calculatedDuration = ppduDurationForSta;
320 Time calculatedDurationUsingList =
322 if (calculatedDuration != knownDuration ||
323 calculatedDuration != calculatedDurationUsingList)
325 std::cerr <<
"size=" << longuestSize <<
" band=" << testedBand <<
" staId=" << staId
326 <<
" nss=" << +txVector.
GetNss(staId) <<
" mode=" << txVector.
GetMode(staId)
327 <<
" channelWidth=" << channelWidth <<
" guardInterval=" << guardInterval
332 <<
" known=" << knownDuration <<
" calculated=" << calculatedDuration
333 <<
" calculatedUsingList=" << calculatedDurationUsingList << std::endl;
342 std::list<uint16_t> staIds,
346 NS_ASSERT(sizes.size() == staIds.size());
348 auto itStaId = staIds.begin();
351 for (
auto& size : sizes)
354 psduMap[*itStaId++] =
357 return WifiPhy::CalculateTxDuration(psduMap, txVector, band);
368 DsssPhy::GetDsssRate11Mbps(),
374 DsssPhy::GetDsssRate11Mbps(),
380 DsssPhy::GetDsssRate11Mbps(),
386 DsssPhy::GetDsssRate11Mbps(),
400 DsssPhy::GetDsssRate11Mbps(),
406 DsssPhy::GetDsssRate11Mbps(),
412 DsssPhy::GetDsssRate11Mbps(),
418 DsssPhy::GetDsssRate11Mbps(),
424 DsssPhy::GetDsssRate11Mbps(),
430 DsssPhy::GetDsssRate11Mbps(),
436 DsssPhy::GetDsssRate11Mbps(),
442 DsssPhy::GetDsssRate11Mbps(),
448 DsssPhy::GetDsssRate5_5Mbps(),
454 DsssPhy::GetDsssRate5_5Mbps(),
460 DsssPhy::GetDsssRate5_5Mbps(),
466 DsssPhy::GetDsssRate5_5Mbps(),
472 DsssPhy::GetDsssRate5_5Mbps(),
478 DsssPhy::GetDsssRate5_5Mbps(),
484 DsssPhy::GetDsssRate5_5Mbps(),
490 DsssPhy::GetDsssRate5_5Mbps(),
496 DsssPhy::GetDsssRate2Mbps(),
502 DsssPhy::GetDsssRate2Mbps(),
508 DsssPhy::GetDsssRate2Mbps(),
514 DsssPhy::GetDsssRate2Mbps(),
520 DsssPhy::GetDsssRate2Mbps(),
526 DsssPhy::GetDsssRate2Mbps(),
532 DsssPhy::GetDsssRate2Mbps(),
538 DsssPhy::GetDsssRate2Mbps(),
544 DsssPhy::GetDsssRate1Mbps(),
550 DsssPhy::GetDsssRate1Mbps(),
556 DsssPhy::GetDsssRate1Mbps(),
562 DsssPhy::GetDsssRate1Mbps(),
568 DsssPhy::GetDsssRate1Mbps(),
574 DsssPhy::GetDsssRate1Mbps(),
580 DsssPhy::GetDsssRate1Mbps(),
586 DsssPhy::GetDsssRate1Mbps(),
594 DsssPhy::GetDsssRate1Mbps(),
603 DsssPhy::GetDsssRate11Mbps(),
609 DsssPhy::GetDsssRate11Mbps(),
615 DsssPhy::GetDsssRate11Mbps(),
627 OfdmPhy::GetOfdmRate54Mbps(),
633 OfdmPhy::GetOfdmRate54Mbps(),
639 OfdmPhy::GetOfdmRate54Mbps(),
650 ErpOfdmPhy::GetErpOfdmRate54Mbps(),
656 ErpOfdmPhy::GetErpOfdmRate54Mbps(),
662 ErpOfdmPhy::GetErpOfdmRate54Mbps(),
719 VhtPhy::GetVhtMcs8(),
725 VhtPhy::GetVhtMcs8(),
731 VhtPhy::GetVhtMcs8(),
737 VhtPhy::GetVhtMcs8(),
743 VhtPhy::GetVhtMcs8(),
749 VhtPhy::GetVhtMcs8(),
755 VhtPhy::GetVhtMcs9(),
761 VhtPhy::GetVhtMcs9(),
767 VhtPhy::GetVhtMcs9(),
773 VhtPhy::GetVhtMcs9(),
779 VhtPhy::GetVhtMcs9(),
785 VhtPhy::GetVhtMcs9(),
791 VhtPhy::GetVhtMcs0(),
797 VhtPhy::GetVhtMcs0(),
803 VhtPhy::GetVhtMcs0(),
809 VhtPhy::GetVhtMcs0(),
815 VhtPhy::GetVhtMcs0(),
821 VhtPhy::GetVhtMcs0(),
827 VhtPhy::GetVhtMcs9(),
833 VhtPhy::GetVhtMcs9(),
839 VhtPhy::GetVhtMcs9(),
845 VhtPhy::GetVhtMcs9(),
851 VhtPhy::GetVhtMcs9(),
857 VhtPhy::GetVhtMcs9(),
863 VhtPhy::GetVhtMcs8(),
869 VhtPhy::GetVhtMcs8(),
875 VhtPhy::GetVhtMcs8(),
881 VhtPhy::GetVhtMcs8(),
887 VhtPhy::GetVhtMcs8(),
893 VhtPhy::GetVhtMcs8(),
1056 HePhy::GetHeMcs11(),
1062 HePhy::GetHeMcs11(),
1068 HePhy::GetHeMcs11(),
1074 HePhy::GetHeMcs11(),
1080 HePhy::GetHeMcs11(),
1086 HePhy::GetHeMcs11(),
1092 HePhy::GetHeMcs11(),
1098 HePhy::GetHeMcs11(),
1104 HePhy::GetHeMcs11(),
1110 HePhy::GetHeMcs11(),
1116 HePhy::GetHeMcs11(),
1122 HePhy::GetHeMcs11(),
1128 HePhy::GetHeMcs11(),
1134 HePhy::GetHeMcs11(),
1140 HePhy::GetHeMcs11(),
1146 HePhy::GetHeMcs11(),
1152 HePhy::GetHeMcs11(),
1158 HePhy::GetHeMcs11(),
1164 HePhy::GetHeMcs11(),
1170 HePhy::GetHeMcs11(),
1176 HePhy::GetHeMcs11(),
1182 HePhy::GetHeMcs11(),
1188 HePhy::GetHeMcs11(),
1194 HePhy::GetHeMcs11(),
1200 HePhy::GetHeMcs11(),
1208 HePhy::GetHeMcs11(),
1216 HePhy::GetHeMcs11(),
1224 HePhy::GetHeMcs11(),
1230 HePhy::GetHeMcs11(),
1242 std::list<uint32_t>{1536, 1536},
1243 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1,
true}, 0, 1},
1244 {{HeRu::RU_242_TONE, 2,
true}, 0, 1}},
1251 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1,
true}, 1, 1},
1252 {{HeRu::RU_242_TONE, 2,
true}, 0, 1}},
1258 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1,
true}, 0, 1},
1259 {{HeRu::RU_242_TONE, 2,
true}, 0, 1}},
1270 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1,
true}, 0, 1},
1271 {{HeRu::RU_242_TONE, 2,
true}, 0, 1}},
1277 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1,
true}, 1, 1},
1278 {{HeRu::RU_242_TONE, 2,
true}, 0, 1}},
1284 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1,
true}, 0, 1},
1285 {{HeRu::RU_242_TONE, 2,
true}, 0, 1}},
1293 Simulator::Destroy();
1307 void DoRun()
override;
1322 :
TestCase(
"Check HE-SIG-B duration computation")
1339 std::list<uint16_t> staIds;
1341 for (
const auto& userInfo : userInfos)
1344 staIds.push_back(staId++);
1355 std::list<HeMuUserInfo> userInfos;
1356 userInfos.push_back({{HeRu::RU_106_TONE, 1,
true}, 11, 1});
1357 userInfos.push_back({{HeRu::RU_106_TONE, 2,
true}, 10, 4});
1362 VhtPhy::GetVhtMcs5(),
1363 "HE-SIG-B should be sent at MCS 5");
1367 "Both users should be on HE-SIG-B content channel 1");
1370 "Both users should be on HE-SIG-B content channel 2");
1373 "HE-SIG-B should only last one OFDM symbol");
1376 userInfos.push_back({{HeRu::RU_52_TONE, 5,
true}, 4, 1});
1377 userInfos.push_back({{HeRu::RU_52_TONE, 6,
true}, 6, 2});
1378 userInfos.push_back({{HeRu::RU_52_TONE, 7,
true}, 5, 3});
1379 userInfos.push_back({{HeRu::RU_52_TONE, 8,
true}, 6, 2});
1384 VhtPhy::GetVhtMcs4(),
1385 "HE-SIG-B should be sent at MCS 4");
1389 "Two users should be on HE-SIG-B content channel 1");
1392 "Four users should be on HE-SIG-B content channel 2");
1395 "HE-SIG-B should only last one OFDM symbol");
1398 userInfos.push_back({{HeRu::RU_26_TONE, 14,
true}, 3, 1});
1403 VhtPhy::GetVhtMcs3(),
1404 "HE-SIG-B should be sent at MCS 3");
1408 "Two users should be on HE-SIG-B content channel 1");
1411 "Five users should be on HE-SIG-B content channel 2");
1414 "HE-SIG-B should last two OFDM symbols");
1417 userInfos.push_back({{HeRu::RU_242_TONE, 3,
true}, 1, 1});
1418 userInfos.push_back({{HeRu::RU_242_TONE, 4,
true}, 4, 1});
1423 VhtPhy::GetVhtMcs1(),
1424 "HE-SIG-B should be sent at MCS 1");
1428 "Three users should be on HE-SIG-B content channel 1");
1431 "Six users should be on HE-SIG-B content channel 2");
1434 "HE-SIG-B should last four OFDM symbols");
1437 userInfos.push_back({{HeRu::RU_996_TONE, 1,
false}, 1, 1});
1442 VhtPhy::GetVhtMcs1(),
1443 "HE-SIG-B should be sent at MCS 1");
1447 "Four users should be on HE-SIG-B content channel 1");
1450 "Seven users should be on HE-SIG-B content channel 2");
1453 "HE-SIG-B should last five OFDM symbols");
1467 void DoRun()
override;
1482 :
TestCase(
"PHY header sections consistency")
1495 "The expected map size (" << expected.size() <<
") was not obtained ("
1496 << obtained.size() <<
")");
1498 auto itObtained = obtained.begin();
1499 auto itExpected = expected.begin();
1500 for (; itObtained != obtained.end() || itExpected != expected.end();)
1503 auto window = itObtained->second.first;
1504 auto mode = itObtained->second.second;
1507 auto windowRef = itExpected->second.first;
1508 auto modeRef = itExpected->second.second;
1512 "The expected PPDU field (" << fieldRef <<
") was not obtained ("
1516 "The expected start time (" << windowRef.first
1517 <<
") was not obtained (" <<
window.first
1521 "The expected stop time (" << windowRef.second
1522 <<
") was not obtained (" <<
window.second
1526 "The expected mode (" << modeRef <<
") was not obtained (" << mode
1544 phyEntity = Create<DsssPhy>();
1545 txVector.
SetMode(DsssPhy::GetDsssRate1Mbps());
1550 nonHtMode = DsssPhy::GetDsssRate1Mbps();
1563 txVector.
SetMode(DsssPhy::GetDsssRate11Mbps());
1564 nonHtMode = DsssPhy::GetDsssRate2Mbps();
1578 std::map<OfdmPhyVariant, std::size_t> variants{
1584 for (
auto variant : variants)
1586 phyEntity = Create<OfdmPhy>(variant.first);
1587 std::size_t ratio = variant.second;
1588 uint16_t bw = 20 / ratio;
1590 txVector.
SetMode(OfdmPhy::GetOfdmRate(12000000 / ratio, bw));
1591 nonHtMode = OfdmPhy::GetOfdmRate(6000000 / ratio, bw);
1594 {{ppduStart, ppduStart +
MicroSeconds(16 * ratio)}, nonHtMode}},
1604 phyEntity = Create<ErpOfdmPhy>();
1606 txVector.
SetMode(ErpOfdmPhy::GetErpOfdmRate(54000000));
1607 nonHtMode = ErpOfdmPhy::GetErpOfdmRate6Mbps();
1617 phyEntity = Create<HtPhy>(4);
1619 txVector.
SetMode(HtPhy::GetHtMcs6());
1620 nonHtMode = OfdmPhy::GetOfdmRate6Mbps();
1652 phyEntity = Create<VhtPhy>();
1655 txVector.
SetMode(VhtPhy::GetVhtMcs7());
1657 WifiMode sigBMode = VhtPhy::GetVhtMcs0();
1695 phyEntity = Create<HePhy>();
1699 txVector.
SetMode(HePhy::GetHeMcs9());
1700 std::map<uint16_t, HeMuUserInfo> userInfoMap = {{1, {{HeRu::RU_106_TONE, 1,
true}, 4, 2}},
1701 {2, {{HeRu::RU_106_TONE, 1,
true}, 9, 1}}};
1702 sigAMode = HePhy::GetVhtMcs0();
1703 sigBMode = HePhy::GetVhtMcs4();
1767 phyEntity = Create<EhtPhy>();
1771 txVector.
SetMode(EhtPhy::GetEhtMcs9());
1772 userInfoMap = {{1, {{HeRu::RU_106_TONE, 1,
true}, 4, 2}},
1773 {2, {{HeRu::RU_106_TONE, 1,
true}, 9, 1}}};
1774 WifiMode uSigMode = EhtPhy::GetVhtMcs0();
1775 WifiMode ehtSigMode = EhtPhy::GetVhtMcs4();
1822 :
TestSuite(
"wifi-devices-tx-duration", UNIT)
static WifiTxVector BuildTxVector(uint16_t bw, std::list< HeMuUserInfo > userInfos)
Build a TXVECTOR for HE MU with the given bandwidth and user information.
void DoRun() override
Implementation to actually run this TestCase.
~HeSigBDurationTest() override
~TxDurationTest() override
static Time CalculateTxDurationUsingList(std::list< uint32_t > sizes, std::list< uint16_t > staIds, WifiTxVector txVector, WifiPhyBand band)
Calculate the overall Tx duration returned by WifiPhy for list of sizes.
static bool CheckMuTxDuration(std::list< uint32_t > sizes, std::list< HeMuUserInfo > userInfos, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the overall Tx duration returned by WifiPhy for a MU PPDU corresponds to a known value.
bool CheckTxDuration(uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the overall tx duration returned by InterferenceHelper corresponds to a known value.
bool CheckPayloadDuration(uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the payload tx duration returned by InterferenceHelper corresponds to a known value.
void DoRun() override
Implementation to actually run this TestCase.
RuType GetRuType() const
Get the RU type.
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
represent a single transmission mode
WifiModulationClass GetModulationClass() const
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
void SetEhtPpduType(uint8_t type)
Set the EHT_PPDU_TYPE parameter.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
void SetRuAllocation(const RuAllocation &ruAlloc)
Set RU Allocation of SIG-B common field.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel() const
Get the number of RUs per HE-SIG-B content channel.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_PPDU_FIELD_SIG_B
SIG-B field.
@ WIFI_PPDU_FIELD_TRAINING
STF + LTF fields (excluding those in preamble for HT-GF)
@ WIFI_PPDU_FIELD_NON_HT_HEADER
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
@ WIFI_PPDU_FIELD_EHT_SIG
EHT-SIG field.
@ WIFI_PPDU_FIELD_HT_SIG
HT-SIG field.
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_U_SIG
U-SIG field.
@ WIFI_PPDU_FIELD_SIG_A
SIG-A field.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
HE MU specific user transmission parameters.
HeRu::RuSpec ru
RU specification.
static TxDurationTestSuite g_txDurationTestSuite
the test suite