23 #include "ns3/simulator.h"
25 #include "ns3/yans-wifi-phy.h"
26 #include "ns3/he-ru.h"
27 #include "ns3/wifi-psdu.h"
28 #include "ns3/packet.h"
29 #include "ns3/dsss-phy.h"
30 #include "ns3/erp-ofdm-phy.h"
31 #include "ns3/he-phy.h"
49 void DoRun (
void)
override;
66 bool CheckPayloadDuration (uint32_t size,
WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval,
WifiPreamble preamble,
Time knownDuration);
81 bool CheckTxDuration (uint32_t size,
WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval,
WifiPreamble preamble,
Time knownDuration);
95 static bool CheckHeMuTxDuration (std::list<uint32_t> sizes, std::list<HeMuUserInfo> userInfos,
96 uint16_t channelWidth, uint16_t guardInterval,
113 static Time CalculateTxDurationUsingList (std::list<uint32_t> sizes, std::list<uint16_t> staIds,
130 txVector.
SetMode (payloadMode);
146 Time calculatedDuration =
phy->GetPayloadDuration (size, txVector, band);
147 if (calculatedDuration != knownDuration)
149 std::cerr <<
"size=" << size
150 <<
" mode=" << payloadMode
151 <<
" channelWidth=" << channelWidth
152 <<
" guardInterval=" << guardInterval
153 <<
" datarate=" << payloadMode.
GetDataRate (channelWidth, guardInterval, 1)
154 <<
" known=" << knownDuration
155 <<
" calculated=" << calculatedDuration
163 calculatedDuration =
phy->GetPayloadDuration (size, txVector, band);
165 if (calculatedDuration != knownDuration)
167 std::cerr <<
"size=" << size
168 <<
" mode=" << payloadMode
169 <<
" channelWidth=" << channelWidth
170 <<
" guardInterval=" << guardInterval
171 <<
" datarate=" << payloadMode.
GetDataRate (channelWidth, guardInterval, 1)
172 <<
" known=" << knownDuration
173 <<
" calculated=" << calculatedDuration
185 txVector.
SetMode (payloadMode);
201 Time calculatedDuration =
phy->CalculateTxDuration (size, txVector, band);
204 if (calculatedDuration != knownDuration || calculatedDuration != calculatedDurationUsingList)
206 std::cerr <<
"size=" << size
207 <<
" mode=" << payloadMode
208 <<
" channelWidth=" << +channelWidth
209 <<
" guardInterval=" << guardInterval
210 <<
" datarate=" << payloadMode.
GetDataRate (channelWidth, guardInterval, 1)
211 <<
" preamble=" << preamble
212 <<
" known=" << knownDuration
213 <<
" calculated=" << calculatedDuration
214 <<
" calculatedUsingList=" << calculatedDurationUsingList
222 calculatedDuration =
phy->CalculateTxDuration (size, txVector, band);
226 if (calculatedDuration != knownDuration || calculatedDuration != calculatedDurationUsingList)
228 std::cerr <<
"size=" << size
229 <<
" mode=" << payloadMode
230 <<
" channelWidth=" << channelWidth
231 <<
" guardInterval=" << guardInterval
232 <<
" datarate=" << payloadMode.
GetDataRate (channelWidth, guardInterval, 1)
233 <<
" preamble=" << preamble
234 <<
" known=" << knownDuration
235 <<
" calculated=" << calculatedDuration
236 <<
" calculatedUsingList=" << calculatedDurationUsingList
246 uint16_t channelWidth, uint16_t guardInterval,
249 NS_ASSERT (sizes.size () == userInfos.size () && sizes.size () > 1);
250 NS_ABORT_MSG_IF (channelWidth < std::accumulate (std::begin (userInfos), std::end (userInfos), 0,
252 {
return prevBw + HeRu::GetBandwidth (info.
ru.
GetRuType ()); }),
253 "Cannot accommodate all the RUs in the provided band");
260 std::list<uint16_t> staIds;
262 for (
const auto & userInfo : userInfos)
265 staIds.push_back (staId++);
269 for (
auto & testedBand : testedBands)
276 uint32_t longuestSize = 0;
277 auto iterStaId = staIds.begin ();
278 for (
auto & size : sizes)
280 Time ppduDurationForSta =
phy->CalculateTxDuration (size, txVector, testedBand, *iterStaId);
281 if (ppduDurationForSta > calculatedDuration)
283 calculatedDuration = ppduDurationForSta;
290 if (calculatedDuration != knownDuration || calculatedDuration != calculatedDurationUsingList)
292 std::cerr <<
"size=" << longuestSize
293 <<
" band=" << testedBand
294 <<
" staId=" << staId
295 <<
" nss=" << +txVector.
GetNss (staId)
296 <<
" mode=" << txVector.
GetMode (staId)
297 <<
" channelWidth=" << channelWidth
298 <<
" guardInterval=" << guardInterval
300 <<
" known=" << knownDuration
301 <<
" calculated=" << calculatedDuration
302 <<
" calculatedUsingList=" << calculatedDurationUsingList
314 NS_ASSERT (sizes.size () == staIds.size ());
316 auto itStaId = staIds.begin ();
319 for (
auto & size : sizes)
322 psduMap[*itStaId++] = Create<WifiPsdu> (Create<Packet> (size - hdr.
GetSerializedSize () - 4), hdr);
324 return WifiPhy::CalculateTxDuration (psduMap, txVector, band);
543 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1,
true}, HePhy::GetHeMcs0 (), 1},
544 {{HeRu::RU_242_TONE, 2,
true}, HePhy::GetHeMcs0 (), 1} },
548 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1,
true}, HePhy::GetHeMcs1 (), 1},
549 {{HeRu::RU_242_TONE, 2,
true}, HePhy::GetHeMcs0 (), 1} },
553 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1,
true}, HePhy::GetHeMcs0 (), 1},
554 {{HeRu::RU_242_TONE, 2,
true}, HePhy::GetHeMcs0 (), 1} },
559 Simulator::Destroy ();
573 void DoRun (
void)
override;
588 :
TestCase (
"Check HE-SIG-B duration computation")
605 std::list<uint16_t> staIds;
607 for (
const auto & userInfo : userInfos)
610 staIds.push_back (staId++);
621 std::list<HeMuUserInfo> userInfos;
622 userInfos.push_back ({{HeRu::RU_106_TONE, 1,
true}, HePhy::GetHeMcs11 (), 1});
623 userInfos.push_back ({{HeRu::RU_106_TONE, 2,
true}, HePhy::GetHeMcs10 (), 4});
627 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 2,
"Both users should be on HE-SIG-B content channel 1");
628 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 0,
"Both users should be on HE-SIG-B content channel 2");
632 userInfos.push_back ({{HeRu::RU_52_TONE, 5,
true}, HePhy::GetHeMcs4 (), 1});
633 userInfos.push_back ({{HeRu::RU_52_TONE, 6,
true}, HePhy::GetHeMcs6 (), 2});
634 userInfos.push_back ({{HeRu::RU_52_TONE, 7,
true}, HePhy::GetHeMcs5 (), 3});
635 userInfos.push_back ({{HeRu::RU_52_TONE, 8,
true}, HePhy::GetHeMcs6 (), 2});
640 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 4,
"Four users should be on HE-SIG-B content channel 2");
644 userInfos.push_back ({{HeRu::RU_26_TONE, 13,
true}, HePhy::GetHeMcs3 (), 1});
649 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 5,
"Five users should be on HE-SIG-B content channel 2");
653 userInfos.push_back ({{HeRu::RU_242_TONE, 3,
true}, HePhy::GetHeMcs1 (), 1});
654 userInfos.push_back ({{HeRu::RU_242_TONE, 4,
true}, HePhy::GetHeMcs4 (), 1});
658 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 3,
"Three users should be on HE-SIG-B content channel 1");
659 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 6,
"Six users should be on HE-SIG-B content channel 2");
663 userInfos.push_back ({{HeRu::RU_996_TONE, 1,
false}, HePhy::GetHeMcs1 (), 1});
667 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 4,
"Four users should be on HE-SIG-B content channel 1");
668 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 7,
"Seven users should be on HE-SIG-B content channel 2");
683 void DoRun (
void)
override;
699 :
TestCase (
"PHY header sections consistency")
711 NS_TEST_EXPECT_MSG_EQ (obtained.size (), expected.size (),
"The expected map size (" << expected.size () <<
") was not obtained (" << obtained.size () <<
")");
713 auto itObtained = obtained.begin ();
714 auto itExpected = expected.begin ();
715 for (;itObtained != obtained.end () || itExpected != expected.end ();)
718 auto window = itObtained->second.first;
719 auto mode = itObtained->second.second;
722 auto windowRef = itExpected->second.first;
723 auto modeRef = itExpected->second.second;
725 NS_TEST_EXPECT_MSG_EQ (field, fieldRef,
"The expected PPDU field (" << fieldRef <<
") was not obtained (" << field <<
")");
728 NS_TEST_EXPECT_MSG_EQ (mode, modeRef,
"The expected mode (" << modeRef <<
") was not obtained (" << mode <<
")");
746 phyEntity = Create<DsssPhy> ();
747 txVector.
SetMode (DsssPhy::GetDsssRate1Mbps ());
752 nonHtMode = DsssPhy::GetDsssRate1Mbps ();
766 txVector.
SetMode (DsssPhy::GetDsssRate11Mbps ());
767 nonHtMode = DsssPhy::GetDsssRate2Mbps ();
783 std::map<OfdmPhyVariant, std::size_t> variants {
788 for (
auto variant : variants)
790 phyEntity = Create<OfdmPhy> (variant.first);
791 std::size_t ratio = variant.second;
792 uint16_t bw = 20 / ratio;
794 txVector.
SetMode (OfdmPhy::GetOfdmRate (12000000 / ratio, bw));
795 nonHtMode = OfdmPhy::GetOfdmRate (6000000 / ratio, bw);
808 phyEntity = Create<ErpOfdmPhy> ();
810 txVector.
SetMode (ErpOfdmPhy::GetErpOfdmRate (54000000));
811 nonHtMode = ErpOfdmPhy::GetErpOfdmRate6Mbps ();
823 phyEntity = Create<HtPhy> (4);
825 txVector.
SetMode (HtPhy::GetHtMcs6 ());
826 nonHtMode = OfdmPhy::GetOfdmRate6Mbps ();
860 phyEntity = Create<VhtPhy> ();
863 txVector.
SetMode (VhtPhy::GetVhtMcs7 ());
865 WifiMode sigBMode = VhtPhy::GetVhtMcs0 ();
907 phyEntity = Create<HePhy> ();
910 txVector.
SetMode (HePhy::GetHeMcs9 ());
911 std::map<uint16_t, HeMuUserInfo> userInfoMap = { { 1, { {HeRu::RU_106_TONE, 1,
true}, HePhy::GetHeMcs4 (), 2 } },
912 { 2, { {HeRu::RU_106_TONE, 1,
true}, HePhy::GetHeMcs9 (), 1 } } };
913 sigAMode = HePhy::GetVhtMcs0 ();
914 sigBMode = HePhy::GetVhtMcs4 ();
983 :
TestSuite (
"wifi-devices-tx-duration", UNIT)