10#include "ns3/he-configuration.h"
11#include "ns3/he-frame-exchange-manager.h"
12#include "ns3/he-phy.h"
13#include "ns3/mobility-helper.h"
14#include "ns3/multi-model-spectrum-channel.h"
15#include "ns3/multi-user-scheduler.h"
16#include "ns3/packet-socket-client.h"
17#include "ns3/packet-socket-helper.h"
18#include "ns3/packet-socket-server.h"
19#include "ns3/packet.h"
20#include "ns3/qos-utils.h"
21#include "ns3/rng-seed-manager.h"
22#include "ns3/spectrum-wifi-helper.h"
23#include "ns3/string.h"
25#include "ns3/wifi-acknowledgment.h"
26#include "ns3/wifi-mac-header.h"
27#include "ns3/wifi-mac-queue.h"
28#include "ns3/wifi-net-device.h"
29#include "ns3/wifi-protection.h"
30#include "ns3/wifi-psdu.h"
88 TypeId(
"ns3::TestMultiUserScheduler")
94 "Modulation class for DL MU PPDUs and TB PPDUs.",
133 : TriggerFrameType::BASIC_TRIGGER);
148 for (
auto it = staList.begin();
it != staList.end();)
150 it =
m_apMac->GetHeSupported(
it->second) ? std::next(
it) : staList.erase(
it);
155 m_apMac->GetWifiPhy()->GetPhyBand(),
156 staList.begin()->first);
162 m_apMac->GetWifiPhy()->GetPhyBand());
185 +
m_apMac->GetWifiPhy()->GetSifs() + duration +
189 NS_LOG_DEBUG(
"Remaining TXOP duration is not enough for BSRP TF exchange");
202 for (
auto it = staList.cbegin();
it != staList.cend();)
204 it =
m_apMac->GetHeSupported(
it->second) ? std::next(
it) : staList.erase(
it);
206 NS_ABORT_MSG_IF(staList.size() != 4,
"There must be 4 associated stations");
212 for (
auto&
sta : staList)
217 for (tid = 0; tid < 8; tid++)
239 NS_LOG_DEBUG(
"Not enough time to send frames to all the stations");
243 std::vector<Ptr<WifiMpdu>>
mpduList;
245 ->GetMpduAggregator()
284 const auto bw =
m_apMac->GetWifiPhy()->GetChannelWidth();
299 for (
auto it = staList.cbegin();
it != staList.cend();)
301 it =
m_apMac->GetHeSupported(
it->second) ? std::next(
it) : staList.erase(
it);
303 NS_ABORT_MSG_IF(staList.size() != 4,
"There must be 4 associated stations");
306 switch (
static_cast<uint16_t
>(bw))
331 for (
auto&
sta : staList)
456 void DoRun()
override;
497 :
TestCase(
"Check correct operation of DL OFDMA acknowledgment sequences"),
499 m_sockets(m_nStations),
500 m_channelWidth(params.channelWidth),
501 m_dlMuAckType(params.dlMuAckType),
502 m_maxAmpduSize(params.maxAmpduSize),
503 m_txopLimit(params.txopLimit),
504 m_continueTxopAfterBsrp(params.continueTxopAfterBsrp),
505 m_skipMuRtsBeforeBsrp(params.skipMuRtsBeforeBsrp),
506 m_protectedIfResponded(params.protectedIfResponded),
507 m_nPktsPerSta(params.nPktsPerSta),
508 m_muEdcaParameterSet(params.muEdcaParameterSet),
509 m_scenario(params.scenario),
510 m_ulPktsGenerated(
false),
513 m_edcaDisabledStartTime(),
588 for (
const auto& [staId, psdu] : psduMap)
591 << psdu->GetHeader(0).GetTypeString() <<
" #MPDUs " << psdu->GetNMpdus()
592 << (psdu->GetHeader(0).IsQosData()
593 ?
" TID " + std::to_string(*psdu->GetTids().begin())
595 << std::setprecision(10) <<
" txDuration " << txDuration <<
" duration/ID "
596 << psdu->GetHeader(0).GetDuration() <<
" #TX PSDUs = " <<
m_txPsdus.size()
597 <<
" size=" << (*psdu->begin())->
GetSize() <<
"\n"
598 <<
"TXVECTOR: " << txVector <<
"\n");
615 while ((mpdu = queue->PeekByTidAndAddress(
i * 2,
616 staDev->GetMac()->GetAddress(),
619 if (mpdu->IsInFlight())
632 psduMap.begin()->second->GetHeader(0).HasData())
640 if (dev->GetAddress() ==
sender)
649 qosTxop->TraceConnectWithoutContext(
658 qosTxop->GetWifiMacQueue()->Flush();
664 else if (!txVector.
IsMu() && psduMap.begin()->second->GetHeader(0).IsBlockAck() &&
665 psduMap.begin()->second->GetHeader(0).GetAddr2() ==
m_apDevice->GetAddress() &&
669 psduMap.begin()->second->GetPayload(0)->PeekHeader(blockAck);
679 else if (!txVector.
IsMu() && psduMap.begin()->second->GetHeader(0).IsTrigger() &&
683 psduMap.
begin()->second->GetPayload(0)->PeekHeader(trigger);
692 client->SetAttribute(
"PacketSize",
UintegerValue(1400 +
i * 100));
698 client->SetStartTime(txDuration);
699 client->SetStopTime(
Seconds(1));
700 client->Initialize();
757 "Expected a Trigger Frame");
762 "Expected one User Info field per station");
765 "Expected the MU-RTS to occupy the entire channel width");
766 for (
const auto& userInfo : trigger)
770 "Unexpected RU Allocation value in MU-RTS");
777 m_txPsdus[1].psduMap.begin()->second->GetNMpdus() == 1 &&
780 "Expected a CTS frame");
783 "Expected the CTS to occupy the entire channel width");
793 "Duration/ID in CTS frame is too long");
799 m_txPsdus[2].psduMap.begin()->second->GetNMpdus() == 1 &&
802 "Expected a CTS frame");
805 "Expected the CTS to occupy the entire channel width");
815 "Duration/ID in CTS frame is too long");
821 m_txPsdus[3].psduMap.begin()->second->GetNMpdus() == 1 &&
824 "Expected a CTS frame");
827 "Expected the CTS to occupy the entire channel width");
837 "Duration/ID in CTS frame is too long");
843 m_txPsdus[4].psduMap.begin()->second->GetNMpdus() == 1 &&
846 "Expected a CTS frame");
849 "Expected the CTS to occupy the entire channel width");
859 "Duration/ID in CTS frame is too long");
874 "Expected a Trigger Frame");
879 "Expected one User Info field per station");
900 m_txPsdus[6].psduMap.begin()->second->GetNMpdus() == 1),
902 "Expected a QoS Null frame in a TB PPDU");
915 uint8_t tid = staId * 2;
923 "QoS Null frame in HE TB PPDU sent too late");
930 "Expected null Duration/ID for QoS Null frame in HE TB PPDU");
939 m_txPsdus[7].psduMap.begin()->second->GetNMpdus() == 1),
941 "Expected a QoS Null frame in a TB PPDU");
954 uint8_t tid = staId * 2;
961 "QoS Null frame in HE TB PPDU sent too late");
968 "Expected null Duration/ID for QoS Null frame in HE TB PPDU");
977 m_txPsdus[8].psduMap.begin()->second->GetNMpdus() == 1),
979 "Expected a QoS Null frame in an HE TB PPDU");
992 uint8_t tid = staId * 2;
999 "QoS Null frame in HE TB PPDU sent too late");
1006 "Expected null Duration/ID for QoS Null frame in HE TB PPDU");
1015 m_txPsdus[9].psduMap.begin()->second->GetNMpdus() == 1),
1017 "Expected a QoS Null frame in an HE TB PPDU");
1030 uint8_t tid = staId * 2;
1037 "QoS Null frame in HE TB PPDU sent too late");
1044 "Expected null Duration/ID for QoS Null frame in HE TB PPDU");
1060 (
secondMuRts ?
"MU-RTS" :
"Basic Trigger Frame") <<
" sent too early");
1066 (
secondMuRts ?
"MU-RTS" :
"Basic Trigger Frame") <<
" sent too late");
1077 "Duration/ID in MU-RTS is too long");
1090 "Expected at least 15 transmitted packet");
1096 "Expected a Trigger Frame");
1101 "Expected one User Info field per station");
1104 "Expected the MU-RTS to occupy the entire channel width");
1105 for (
const auto& userInfo : trigger)
1109 "Unexpected RU Allocation value in MU-RTS");
1120 m_txPsdus[11].psduMap.begin()->second->GetNMpdus() == 1 &&
1123 "Expected a CTS frame");
1126 "Expected the CTS to occupy the entire channel width");
1136 "Duration/ID in CTS frame is too long");
1142 m_txPsdus[12].psduMap.begin()->second->GetNMpdus() == 1 &&
1145 "Expected a CTS frame");
1148 "Expected the CTS to occupy the entire channel width");
1158 "Duration/ID in CTS frame is too long");
1164 m_txPsdus[13].psduMap.begin()->second->GetNMpdus() == 1 &&
1167 "Expected a CTS frame");
1170 "Expected the CTS to occupy the entire channel width");
1180 "Duration/ID in CTS frame is too long");
1186 m_txPsdus[14].psduMap.begin()->second->GetNMpdus() == 1 &&
1189 "Expected a CTS frame");
1192 "Expected the CTS to occupy the entire channel width");
1202 "Duration/ID in CTS frame is too long");
1220 "Expected a Trigger Frame");
1225 "Expected one User Info field per station");
1237 m_txPsdus[16].psduMap.begin()->second->GetNMpdus() == 2 &&
1238 m_txPsdus[16].psduMap.begin()->second->GetHeader(0).IsQosData() &&
1239 m_txPsdus[16].psduMap.begin()->second->GetHeader(1).IsQosData()),
1241 "Expected 2 QoS data frames in an HE TB PPDU");
1247 "QoS data frames in HE TB PPDU sent too late");
1256 m_txPsdus[17].psduMap.begin()->second->GetNMpdus() == 2 &&
1257 m_txPsdus[17].psduMap.begin()->second->GetHeader(0).IsQosData() &&
1258 m_txPsdus[17].psduMap.begin()->second->GetHeader(1).IsQosData()),
1260 "Expected 2 QoS data frames in an HE TB PPDU");
1265 "QoS data frames in HE TB PPDU sent too late");
1274 m_txPsdus[18].psduMap.begin()->second->GetNMpdus() == 2 &&
1275 m_txPsdus[18].psduMap.begin()->second->GetHeader(0).IsQosData() &&
1276 m_txPsdus[18].psduMap.begin()->second->GetHeader(1).IsQosData()),
1278 "Expected 2 QoS data frames in an HE TB PPDU");
1283 "QoS data frames in HE TB PPDU sent too late");
1292 m_txPsdus[19].psduMap.begin()->second->GetNMpdus() == 2 &&
1293 m_txPsdus[19].psduMap.begin()->second->GetHeader(0).IsQosData() &&
1294 m_txPsdus[19].psduMap.begin()->second->GetHeader(1).IsQosData()),
1296 "Expected 2 QoS data frames in an HE TB PPDU");
1301 "QoS data frames in HE TB PPDU sent too late");
1312 "Expected a Block Ack");
1317 "Expected one Per AID TID Info subfield per station");
1318 for (uint8_t
i = 0;
i < 4;
i++)
1331 "Duration/ID in Multi-STA BlockAck is too short");
1334 "Duration/ID in Multi-STA BlockAck is too long");
1343 "Expected at least 26 transmitted packet");
1349 "Expected a Trigger Frame");
1354 "Expected one User Info field per station");
1357 "Expected the MU-RTS to occupy the entire channel width");
1358 for (
const auto& userInfo : trigger)
1362 "Unexpected RU Allocation value in MU-RTS");
1374 m_txPsdus[22].psduMap.begin()->second->GetNMpdus() == 1 &&
1377 "Expected a CTS frame");
1380 "Expected the CTS to occupy the entire channel width");
1390 "Duration/ID in CTS frame is too long");
1396 m_txPsdus[23].psduMap.begin()->second->GetNMpdus() == 1 &&
1399 "Expected a CTS frame");
1402 "Expected the CTS to occupy the entire channel width");
1412 "Duration/ID in CTS frame is too long");
1418 m_txPsdus[24].psduMap.begin()->second->GetNMpdus() == 1 &&
1421 "Expected a CTS frame");
1424 "Expected the CTS to occupy the entire channel width");
1434 "Duration/ID in CTS frame is too long");
1440 m_txPsdus[25].psduMap.begin()->second->GetNMpdus() == 1 &&
1443 "Expected a CTS frame");
1446 "Expected the CTS to occupy the entire channel width");
1456 "Duration/ID in CTS frame is too long");
1472 "Expected a DL MU PPDU");
1475 "Expected 4 PSDUs within the DL MU PPDU");
1479 "TX duration cannot exceed max PPDU duration");
1480 for (
auto& psdu :
m_txPsdus[26].psduMap)
1484 "Max A-MPDU size exceeded");
1492 for (
auto& psdu :
m_txPsdus[26].psduMap)
1502 "Duration/ID must be the same for all PSDUs");
1541 "Expected a Block Ack");
1552 "Duration/ID in 1st BlockAck frame is too short");
1555 "Duration/ID in 1st BlockAck is too long");
1561 "Expected a Block Ack Request");
1567 "First Block Ack Request sent too late");
1577 "Duration/ID in BlockAckReq is too short");
1580 "Duration/ID in BlockAckReq is too long");
1587 "Expected a Block Ack");
1599 "Duration/ID in BlockAck is too long");
1606 "Duration/ID in BlockAck is too short");
1609 "Duration/ID in BlockAck is too long");
1612 "Expected null Duration/ID for BlockAck");
1619 "Expected a Block Ack Request");
1625 "Second Block Ack Request sent too late");
1635 "Duration/ID in BlockAckReq is too short");
1638 "Duration/ID in BlockAckReq is too long");
1645 "Expected a Block Ack");
1657 "Duration/ID in BlockAck is too long");
1664 "Duration/ID in BlockAck is too short");
1667 "Duration/ID in BlockAck is too long");
1670 "Expected null Duration/ID for BlockAck");
1677 "Expected a Block Ack Request");
1683 "Third Block Ack Request sent too late");
1693 "Duration/ID in BlockAckReq is too short");
1696 "Duration/ID in BlockAckReq is too long");
1703 "Expected a Block Ack");
1715 "Duration/ID in BlockAck is too long");
1722 "Duration/ID in BlockAck is too short");
1725 "Duration/ID in BlockAck is too long");
1728 "Expected null Duration/ID for BlockAck");
1758 "Expected a MU-BAR Trigger Frame");
1766 "Duration/ID in MU-BAR Trigger Frame is too short");
1769 "Duration/ID in MU-BAR Trigger Frame is too long");
1774 m_txPsdus[28].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1776 "Expected a Block Ack");
1782 "Block Ack in HE TB PPDU sent too late");
1791 "Expected null Duration/ID for BlockAck");
1797 m_txPsdus[29].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1799 "Expected a Block Ack");
1804 "Block Ack in HE TB PPDU sent too late");
1810 "Duration/ID in 1st BlockAck is too long");
1815 "Expected null Duration/ID for BlockAck");
1821 m_txPsdus[30].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1823 "Expected a Block Ack");
1828 "Block Ack in HE TB PPDU sent too late");
1834 "Duration/ID in 1st BlockAck is too long");
1839 "Expected null Duration/ID for BlockAck");
1845 m_txPsdus[31].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1847 "Expected a Block Ack");
1852 "Block Ack in HE TB PPDU sent too late");
1858 "Duration/ID in 1st BlockAck is too long");
1863 "Expected null Duration/ID for BlockAck");
1889 for (
auto& psdu :
m_txPsdus[26].psduMap)
1893 "Expected an aggregated MU-BAR Trigger Frame");
1899 m_txPsdus[27].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1901 "Expected a Block Ack");
1907 "Block Ack in HE TB PPDU sent too late");
1916 "Expected null Duration/ID for BlockAck");
1922 m_txPsdus[28].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1924 "Expected a Block Ack");
1929 "Block Ack in HE TB PPDU sent too late");
1938 "Expected null Duration/ID for BlockAck");
1944 m_txPsdus[29].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1946 "Expected a Block Ack");
1951 "Block Ack in HE TB PPDU sent too late");
1960 "Expected null Duration/ID for BlockAck");
1966 m_txPsdus[30].psduMap.begin()->second->GetHeader(0).IsBlockAck()),
1968 "Expected a Block Ack");
1973 "Block Ack in HE TB PPDU sent too late");
1982 "Expected null Duration/ID for BlockAck");
1990 "Not all DL packets have been received");
2000 !
m_txPsdus[
i].psduMap.begin()->second->GetHeader(0).IsCts() &&
2001 m_txPsdus[
i].psduMap.begin()->second->GetHeader(0).GetAddr2() !=
2009 "A station transmitted before the MU EDCA timer expired");
2021 "A station did not set the correct MU CW min");
2038 wifiApNode.Create(1);
2055 phy.SetErrorRateModel(
"ns3::NistErrorRateModel");
2060 phy.Set(
"ChannelSettings",
StringValue(
"{36, 20, BAND_5GHZ, 0}"));
2063 phy.Set(
"ChannelSettings",
StringValue(
"{38, 40, BAND_5GHZ, 0}"));
2066 phy.Set(
"ChannelSettings",
StringValue(
"{42, 80, BAND_5GHZ, 0}"));
2069 phy.Set(
"ChannelSettings",
StringValue(
"{50, 160, BAND_5GHZ, 0}"));
2072 NS_ABORT_MSG(
"Invalid channel bandwidth (must be 20, 40, 80 or 160)");
2117 wifi.SetRemoteStationManager(
"ns3::ConstantRateWifiManager",
2120 wifi.ConfigHeOptions(
"MuBeAifsn",
2138 mac.SetType(
"ns3::StaWifiMac",
2146 "BE_BlockAckThreshold",
2153 "BK_BlockAckThreshold",
2160 "VI_BlockAckThreshold",
2167 "VO_BlockAckThreshold",
2185 mac.SetType(
"ns3::ApWifiMac",
"BeaconGeneration",
BooleanValue(
true));
2186 mac.SetMultiUserScheduler(
2187 "ns3::TestMultiUserScheduler",
2191 "AccessReqInterval",
2193 "DelayAccessReqUponAccess",
2195 "DefaultTbPpduDuration",
2197 mac.SetProtectionManager(
"ns3::WifiDefaultProtectionManager",
2200 "SkipMuRtsBeforeBsrp",
2202 mac.SetAckManager(
"ns3::WifiDefaultAckManager",
2203 "DlMuAckSequenceType",
2205 mac.SetFrameExchangeManager(
"ProtectedIfResponded",
2207 "ContinueTxopAfterBsrp",
2226 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
2227 mobility.Install(wifiApNode);
2228 mobility.Install(wifiStaNodes);
2240 dev->GetMac()->GetQosTxop(
AC_BE)->SetAifsn(3);
2241 dev->GetMac()->GetQosTxop(
AC_BK)->SetAifsn(3);
2242 dev->GetMac()->GetQosTxop(
AC_VI)->SetAifsn(3);
2243 dev->GetMac()->GetQosTxop(
AC_VO)->SetAifsn(3);
2266 wifiApNode.Get(0)->AddApplication(
client1);
2278 wifiApNode.Get(0)->AddApplication(
client2);
2283 server->SetLocal(socket);
2284 wifiStaNodes.Get(
i)->AddApplication(server);
2285 server->SetStartTime(
Seconds(0));
2286 server->SetStopTime(
Seconds(3));
2304 wifiStaNodes.Get(
i)->AddApplication(
client1);
2313 wifiApNode.Get(0)->AddApplication(server);
2314 server->SetStartTime(
Seconds(0));
2315 server->SetStopTime(
Seconds(3));
2318 Config::Connect(
"/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
2321 Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
2328 m_apDevice->GetMac()->GetWifiPhy()->GetSlot(),
2353 using MuEdcaParams = std::initializer_list<OfdmaAckSequenceTest::MuEdcaParameterSet>;
2355 for (
auto& muEdcaParameterSet : MuEdcaParams{{0, 0, 0, 0} ,
2356 {0, 127, 2047, 100} ,
2357 {10, 127, 2047, 100} })
2359 for (
const auto scenario :
2363 {.channelWidth =
MHz_u{20},
2365 .maxAmpduSize = 10000,
2367 .continueTxopAfterBsrp =
false,
2368 .skipMuRtsBeforeBsrp =
true,
2369 .protectedIfResponded =
false,
2371 .muEdcaParameterSet = muEdcaParameterSet,
2372 .scenario = scenario}),
2373 TestCase::Duration::QUICK);
2375 {.channelWidth =
MHz_u{20},
2377 .maxAmpduSize = 10000,
2379 .continueTxopAfterBsrp =
false,
2380 .skipMuRtsBeforeBsrp =
false,
2381 .protectedIfResponded =
false,
2383 .muEdcaParameterSet = muEdcaParameterSet,
2384 .scenario = scenario}),
2385 TestCase::Duration::QUICK);
2387 {.channelWidth =
MHz_u{20},
2389 .maxAmpduSize = 10000,
2391 .continueTxopAfterBsrp =
false,
2392 .skipMuRtsBeforeBsrp =
true,
2393 .protectedIfResponded =
true,
2395 .muEdcaParameterSet = muEdcaParameterSet,
2396 .scenario = scenario}),
2397 TestCase::Duration::QUICK);
2401 .maxAmpduSize = 10000,
2403 .continueTxopAfterBsrp =
true,
2404 .skipMuRtsBeforeBsrp =
false,
2405 .protectedIfResponded =
false,
2407 .muEdcaParameterSet = muEdcaParameterSet,
2408 .scenario = scenario}),
2409 TestCase::Duration::QUICK);
2413 .maxAmpduSize = 10000,
2415 .continueTxopAfterBsrp =
false,
2416 .skipMuRtsBeforeBsrp =
true,
2417 .protectedIfResponded =
false,
2419 .muEdcaParameterSet = muEdcaParameterSet,
2420 .scenario = scenario}),
2421 TestCase::Duration::QUICK);
2425 .maxAmpduSize = 10000,
2427 .continueTxopAfterBsrp =
true,
2428 .skipMuRtsBeforeBsrp =
false,
2429 .protectedIfResponded =
true,
2431 .muEdcaParameterSet = muEdcaParameterSet,
2432 .scenario = scenario}),
2433 TestCase::Duration::QUICK);
Test OFDMA acknowledgment sequences.
OfdmaAckSequenceTest(const Params ¶ms)
Constructor.
std::vector< FrameInfo > m_txPsdus
transmitted PSDUs
bool m_protectedIfResponded
A STA is considered protected if responded to previous frame.
Time m_edcaDisabledStartTime
time when disabling EDCA started
uint16_t m_flushed
number of DL packets flushed after DL MU PPDU
uint8_t m_muRtsRuAllocation
B7-B1 of RU Allocation subfield of MU-RTS.
void Transmit(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when FrameExchangeManager passes PSDUs to the PHY.
static constexpr uint16_t m_muTimerRes
MU timer resolution in usec.
uint16_t m_received
number of packets received by the stations
void CheckResults(Time sifs, Time slotTime, uint8_t aifsn)
Check correctness of transmitted frames.
MHz_u m_channelWidth
PHY channel bandwidth.
WifiAcknowledgment::Method m_dlMuAckType
DL MU ack sequence type.
bool m_ulPktsGenerated
whether UL packets for HE TB PPDUs have been generated
uint16_t m_nPktsPerSta
number of packets to send to each station
NetDeviceContainer m_staDevices
stations' devices
std::vector< PacketSocketAddress > m_sockets
packet socket addresses for STAs
uint16_t m_txopLimit
TXOP limit in microseconds.
void DoRun() override
Implementation to actually run this TestCase.
void L7Receive(std::string context, Ptr< const Packet > p, const Address &addr)
Function to trace packets received by the server application.
WifiOfdmaScenario m_scenario
OFDMA scenario to test.
~OfdmaAckSequenceTest() override
uint32_t m_maxAmpduSize
maximum A-MPDU size in bytes
Ptr< WifiNetDevice > m_apDevice
AP's device.
std::vector< uint32_t > m_cwValues
CW used by stations after MU exchange.
void TraceCw(uint32_t staIndex, uint32_t cw, uint8_t)
Function to trace CW value used by the given station after the MU exchange.
WifiPreamble m_tbPreamble
expected preamble type for TB PPDUs
uint16_t m_nStations
number of stations
bool m_skipMuRtsBeforeBsrp
whether to skip MU-RTS before BSRP TF
MuEdcaParameterSet m_muEdcaParameterSet
MU EDCA Parameter Set.
bool m_continueTxopAfterBsrp
whether to continue TXOP after BSRP TF when TXOP limit is zero
const Time m_defaultTbPpduDuration
default TB PPDU duration
WifiPreamble m_dlMuPreamble
expected preamble type for DL MU PPDUs
Dummy Multi User Scheduler used to test OFDMA ack sequences.
WifiPsduMap m_psduMap
the DL MU PPDU to transmit
TxFormat m_txFormat
the format of next transmission
WifiModulationClass m_modClass
modulation class for DL MU PPDUs and TB PPDUs
WifiTxVector m_txVector
the TX vector for MU PPDUs
UlMuInfo ComputeUlMuInfo() override
Prepare the information required to solicit an UL MU transmission.
TriggerFrameType m_ulTriggerType
Trigger Frame type for UL MU.
WifiTxParameters m_txParams
TX parameters.
TxFormat SelectTxFormat() override
Select the format of the next transmission.
void ComputeWifiTxVector()
Compute the TX vector to use for MU PPDUs.
~TestMultiUserScheduler() override
static TypeId GetTypeId()
Get the type ID.
WifiMacHeader m_triggerHdr
MAC header for Trigger Frame.
CtrlTriggerHeader m_trigger
Trigger Frame to send.
DlMuInfo ComputeDlMuInfo() override
Compute the information required to perform a DL MU transmission.
wifi MAC OFDMA Test Suite
a polymophic address class
AttributeValue implementation for Boolean.
Hold variables of type enum.
static std::pair< uint16_t, Time > ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Compute the L-SIG length value corresponding to the given HE TB PPDU duration.
RuType
The different HE Resource Unit (RU) types.
static Mac48Address GetBroadcast()
Helper class used to assign positions and mobility models to nodes.
MultiUserScheduler is an abstract base class defining the API that APs supporting at least VHT can us...
bool m_initialFrame
true if a TXOP is being started
Ptr< ApWifiMac > m_apMac
the AP wifi MAC
Time m_availableTime
the time available for frame exchange
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId) const
Get the station manager attached to the AP on the given link.
uint32_t GetMaxSizeOfQosNullAmpdu(const CtrlTriggerHeader &trigger) const
Get the maximum size in bytes among the A-MPDUs containing QoS Null frames and solicited by the given...
MHz_u m_allowedWidth
the allowed width for the current transmission
Ptr< HeFrameExchangeManager > GetHeFem(uint8_t linkId) const
Get the HE Frame Exchange Manager attached to the AP on the given link.
TxFormat
Enumeration of the possible transmission formats.
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Smart pointer class similar to boost::intrusive_ptr.
static uint64_t GetRun()
Get the current run number.
static uint32_t GetSeed()
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
AttributeValue implementation for Ssid.
Hold variables of type string.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
create MAC layers for a ns3::WifiNetDevice.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
std::optional< Time > m_txDuration
TX duration of the frame.
std::unique_ptr< WifiProtection > m_protection
protection method
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
void Clear()
Reset the TX parameters.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetRuAllocation(const RuAllocation &ruAlloc, uint8_t p20Index)
Set RU_ALLOCATION field.
void SetEhtPpduType(uint8_t type)
Set the EHT_PPDU_TYPE parameter.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetGuardInterval(Time guardInterval)
Sets the guard interval duration (in nanoseconds)
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
WifiPreamble GetPreambleType() const
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
void SetGlobal(std::string name, const AttributeValue &value)
void SetDefault(std::string name, const AttributeValue &value)
void Connect(std::string path, const CallbackBase &cb)
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#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_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
#define NS_TEST_EXPECT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to limit and report if not.
#define NS_TEST_EXPECT_MSG_LT_OR_EQ(actual, limit, msg)
Test that an actual value is less than or equal to a limit and report if not.
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
#define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to a limit and report and abort 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.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
WifiOfdmaScenario
The scenarios.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
TriggerFrameType
The different Trigger frame types.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time GetPpduMaxTime(WifiPreamble preamble)
Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for the PHY layers defining the aPPD...
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr, bool isAmpdu)
Return the total size of the packet after WifiMacHeader and FCS trailer have been added.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
std::unordered_map< uint16_t, Ptr< WifiPsdu > > WifiPsduMap
Map of PSDUs indexed by STA-ID.
Information about transmitted frames.
Time startTx
start TX time
WifiTxVector txVector
TXVECTOR.
WifiConstPsduMap psduMap
transmitted PSDU map
uint8_t muAifsn
MU AIFS (0 to disable EDCA)
uint16_t muCwMin
MU CW min.
uint8_t muTimer
MU EDCA Timer in units of 8192 microseconds (0 not to use MU EDCA)
uint16_t muCwMax
MU CW max.
Parameters for the OFDMA acknowledgment sequences test.
bool protectedIfResponded
A STA is considered protected if responded to previous frame.
bool continueTxopAfterBsrp
whether to continue TXOP after BSRP TF when TXOP limit is 0
uint16_t txopLimit
TXOP limit in microseconds.
uint16_t nPktsPerSta
number of packets to send to each station
WifiAcknowledgment::Method dlMuAckType
DL MU ack sequence type.
MuEdcaParameterSet muEdcaParameterSet
MU EDCA Parameter Set.
MHz_u channelWidth
PHY channel bandwidth.
uint32_t maxAmpduSize
maximum A-MPDU size in bytes
bool skipMuRtsBeforeBsrp
whether to skip MU-RTS before BSRP TF
WifiOfdmaScenario scenario
OFDMA scenario to test.
Information to be provided in case of DL MU transmission.
Information to be provided in case of UL MU transmission.
Method
Available acknowledgment methods.
static WifiMacOfdmaTestSuite g_wifiMacOfdmaTestSuite
the test suite