A Discrete-Event Network Simulator
API
wifi-dynamic-bw-op-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #include "ns3/channel-access-manager.h"
21 #include "ns3/config.h"
22 #include "ns3/mobility-helper.h"
23 #include "ns3/multi-model-spectrum-channel.h"
24 #include "ns3/packet-socket-client.h"
25 #include "ns3/packet-socket-helper.h"
26 #include "ns3/packet-socket-server.h"
27 #include "ns3/qos-txop.h"
28 #include "ns3/rng-seed-manager.h"
29 #include "ns3/spectrum-wifi-helper.h"
30 #include "ns3/string.h"
31 #include "ns3/test.h"
32 #include "ns3/wifi-mac.h"
33 #include "ns3/wifi-net-device.h"
34 #include "ns3/wifi-psdu.h"
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE("WifiDynamicBwOpTestSuite");
39 
51 {
52  public:
59  WifiUseAvailBwTest(std::initializer_list<std::string> channelStr, uint16_t bss0Width);
60  ~WifiUseAvailBwTest() override;
61 
68  void L7Receive(uint8_t bss, Ptr<const Packet> p, const Address& addr);
76  void Transmit(uint8_t bss, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
80  void CheckResults();
81 
82  private:
83  void DoRun() override;
84 
86  struct FrameInfo
87  {
90  uint8_t bss;
92  std::size_t nMpdus;
94  };
95 
96  std::vector<std::string> m_channelStr;
97  uint16_t m_bss0Width;
101  std::array<PacketSocketAddress, 2> m_sockets;
102  std::vector<FrameInfo> m_txPsdus;
103  uint8_t m_txPkts;
105  std::array<uint8_t, 2> m_rcvPkts;
106 };
107 
108 WifiUseAvailBwTest::WifiUseAvailBwTest(std::initializer_list<std::string> channelStr,
109  uint16_t bss0Width)
110  : TestCase("Check transmission on available bandwidth"),
111  m_channelStr(channelStr),
112  m_bss0Width(bss0Width),
113  m_txPkts(bss0Width / 10), // so that they all fit in an A-MPDU
114  m_rcvPkts({0, 0})
115 {
116 }
117 
119 {
120 }
121 
122 void
124 {
125  NS_LOG_INFO("Received " << p->GetSize() << " bytes in BSS " << +bss);
126  m_rcvPkts[bss]++;
127 }
128 
129 void
131  WifiConstPsduMap psduMap,
132  WifiTxVector txVector,
133  double txPowerW)
134 {
135  auto psdu = psduMap.begin()->second;
136  Time now = Simulator::Now();
137 
138  // Log all frames that are not management frames (we are only interested in data
139  // frames and acknowledgments) and have been transmitted after 400ms (so as to
140  // skip association requests/responses)
141  if (!psdu->GetHeader(0).IsMgt() && now > MilliSeconds(400))
142  {
143  m_txPsdus.push_back({now,
144  WifiPhy::CalculateTxDuration(psduMap, txVector, WIFI_PHY_BAND_5GHZ),
145  bss,
146  psdu->GetHeader(0),
147  psdu->GetNMpdus(),
148  txVector});
149  }
150 
151  NS_LOG_INFO(now << " BSS " << +bss << " " << psdu->GetHeader(0).GetTypeString() << " seq "
152  << psdu->GetHeader(0).GetSequenceNumber() << " to " << psdu->GetAddr1()
153  << " #MPDUs " << psdu->GetNMpdus() << " size " << psdu->GetSize()
154  << " TX duration "
155  << WifiPhy::CalculateTxDuration(psduMap, txVector, WIFI_PHY_BAND_5GHZ) << "\n"
156  << "TXVECTOR " << txVector << "\n");
157 
158  // when AP of BSS 1 starts transmitting (after 1.5 s), we generate packets
159  // for the AP of BSS 0 to transmit
160  if (bss == 1 && psdu->GetNMpdus() == m_txPkts && now >= Seconds(1.5))
161  {
162  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
163  client->SetAttribute("PacketSize", UintegerValue(2000));
164  client->SetAttribute("MaxPackets", UintegerValue(m_txPkts));
165  client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
166  client->SetRemote(m_sockets[0]);
167  m_apDevices.Get(0)->GetNode()->AddApplication(client);
168  client->SetStartTime(Seconds(0)); // start now
169  client->SetStopTime(Seconds(1.0)); // stop in a second
170  client->Initialize();
171 
172  // after 1us (to allow for propagation delay), the largest idle primary
173  // channel on the AP of BSS 0 should be the expected one
174  Simulator::Schedule(MicroSeconds(1), [&]() {
175  auto mac = StaticCast<WifiNetDevice>(m_apDevices.Get(0))->GetMac();
176  auto cam = mac->GetChannelAccessManager();
178  cam->GetLargestIdlePrimaryChannel(MicroSeconds(1), Simulator::Now()),
179  m_bss0Width,
180  "Unexpected width of the largest idle primary channel");
181  });
182  }
183 }
184 
185 void
187 {
188  RngSeedManager::SetSeed(1);
189  RngSeedManager::SetRun(40);
190  int64_t streamNumber = 100;
191 
192  NodeContainer wifiApNodes(2);
194 
195  auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
196  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
197  spectrumChannel->AddPropagationLossModel(lossModel);
199  CreateObject<ConstantSpeedPropagationDelayModel>();
200  spectrumChannel->SetPropagationDelayModel(delayModel);
201 
203  phy.SetChannel(spectrumChannel);
204 
206  wifi.SetStandard(WIFI_STANDARD_80211ax);
207  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
208  "DataMode",
209  StringValue("HeMcs0"),
210  "ControlMode",
211  StringValue("OfdmRate6Mbps"));
212 
213  WifiMacHelper apMac;
214  apMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(Ssid("dynamic-bw-op-ssid")));
215 
216  WifiMacHelper staMac;
217  staMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(Ssid("dynamic-bw-op-ssid")));
218 
219  // BSS 0
220  phy.Set("ChannelSettings", StringValue(m_channelStr.at(0)));
221 
222  m_apDevices = wifi.Install(phy, apMac, wifiApNodes.Get(0));
223  m_staDevices = wifi.Install(phy, staMac, wifiStaNodes.Get(0));
224 
225  // BSS 1
226  phy.Set("ChannelSettings", StringValue(m_channelStr.at(1)));
227 
228  m_apDevices.Add(wifi.Install(phy, apMac, wifiApNodes.Get(1)));
229  m_staDevices.Add(wifi.Install(phy, staMac, wifiStaNodes.Get(1)));
230 
231  // schedule association requests at different times
232  Ptr<WifiNetDevice> dev;
233 
234  // Assign fixed streams to random variables in use
235  streamNumber += wifi.AssignStreams(m_apDevices, streamNumber);
236  streamNumber += wifi.AssignStreams(m_staDevices, streamNumber);
237 
239  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
240 
241  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
242  positionAlloc->Add(Vector(50.0, 0.0, 0.0));
243  positionAlloc->Add(Vector(0.0, 50.0, 0.0));
244  positionAlloc->Add(Vector(50.0, 50.0, 0.0));
245  mobility.SetPositionAllocator(positionAlloc);
246 
247  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
248  mobility.Install(wifiApNodes);
249  mobility.Install(wifiStaNodes);
250 
251  NS_LOG_INFO("Position of AP (BSS 0) = "
252  << wifiApNodes.Get(0)->GetObject<MobilityModel>()->GetPosition());
253  NS_LOG_INFO("Position of AP (BSS 1) = "
254  << wifiApNodes.Get(1)->GetObject<MobilityModel>()->GetPosition());
255  NS_LOG_INFO("Position of STA (BSS 0) = "
256  << wifiStaNodes.Get(0)->GetObject<MobilityModel>()->GetPosition());
257  NS_LOG_INFO("Position of STA (BSS 1) = "
258  << wifiStaNodes.Get(1)->GetObject<MobilityModel>()->GetPosition());
259 
260  PacketSocketHelper packetSocket;
261  packetSocket.Install(wifiApNodes);
262  packetSocket.Install(wifiStaNodes);
263 
264  // DL frames
265  for (uint8_t bss : {0, 1})
266  {
267  m_sockets[bss].SetSingleDevice(m_apDevices.Get(bss)->GetIfIndex());
268  m_sockets[bss].SetPhysicalAddress(m_staDevices.Get(bss)->GetAddress());
269  m_sockets[bss].SetProtocol(1);
270 
271  // the first client application generates two packets in order
272  // to trigger the establishment of a Block Ack agreement
273  Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient>();
274  client1->SetAttribute("PacketSize", UintegerValue(500));
275  client1->SetAttribute("MaxPackets", UintegerValue(2));
276  client1->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
277  client1->SetRemote(m_sockets[bss]);
278  wifiApNodes.Get(bss)->AddApplication(client1);
279  client1->SetStartTime(Seconds(0.5) + bss * MilliSeconds(500));
280  client1->SetStopTime(Seconds(2.0));
281 
282  // At time 1.5, start a transmission in BSS 1
283  if (bss == 1)
284  {
285  Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient>();
286  client2->SetAttribute("PacketSize", UintegerValue(2000));
287  client2->SetAttribute("MaxPackets", UintegerValue(m_txPkts));
288  client2->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
289  client2->SetRemote(m_sockets[bss]);
290  wifiApNodes.Get(bss)->AddApplication(client2);
291  client2->SetStartTime(Seconds(1.5));
292  client2->SetStopTime(Seconds(2.0));
293  }
294 
295  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
296  server->SetLocal(m_sockets[bss]);
297  wifiStaNodes.Get(bss)->AddApplication(server);
298  server->SetStartTime(Seconds(0.0));
299  server->SetStopTime(Seconds(2.0));
300 
301  // Trace received packets on non-AP STAs
302  Config::ConnectWithoutContext("/NodeList/" + std::to_string(2 + bss) +
303  "/ApplicationList/*/$ns3::PacketSocketServer/Rx",
304  MakeCallback(&WifiUseAvailBwTest::L7Receive, this).Bind(bss));
305  // Trace PSDUs passed to the PHY of the AP
306  Config::ConnectWithoutContext("/NodeList/" + std::to_string(bss) +
307  "/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
308  MakeCallback(&WifiUseAvailBwTest::Transmit, this).Bind(bss));
309  // Trace PSDUs passed to the PHY of the non-AP STA
310  Config::ConnectWithoutContext("/NodeList/" + std::to_string(2 + bss) +
311  "/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
312  MakeCallback(&WifiUseAvailBwTest::Transmit, this).Bind(bss));
313  }
314 
315  Simulator::Stop(Seconds(2));
316  Simulator::Run();
317 
318  CheckResults();
319 
320  Simulator::Destroy();
321 }
322 
323 void
325 {
326  NS_TEST_ASSERT_MSG_EQ(m_txPsdus.size(), 12, "Expected 12 transmitted frames");
327 
328  // first logged frames are Acks after ADDBA Request/Response frames
329  auto psduIt = m_txPsdus.begin();
330  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsAck(), true, "Expected Ack after ADDBA Request");
331  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 0, "Expected a transmission in BSS 0");
332  psduIt++;
333 
334  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsAck(), true, "Expected Ack after ADDBA Response");
335  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 0, "Expected a transmission in BSS 0");
336  psduIt++;
337 
338  // the first data frame is an A-MPDU sent by the AP of BSS 0 right after the
339  // establishment of the Block Ack agreement
340  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsQosData(), true, "Expected a QoS data frame");
341  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 0, "Expected a transmission in BSS 0");
342  NS_TEST_EXPECT_MSG_EQ(psduIt->nMpdus, 2, "Expected an A-MPDU of 2 MPDUs after Block Ack");
344  psduIt->txVector.GetChannelWidth(),
345  StaticCast<WifiNetDevice>(m_apDevices.Get(0))->GetPhy()->GetChannelWidth(),
346  "Expected a transmission on the whole channel width");
347  psduIt++;
348 
349  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsBlockAck(), true, "Expected Block Ack after data frame");
350  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 0, "Expected a transmission in BSS 0");
351  psduIt++;
352 
353  // same sequence for BSS 1
354  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsAck(), true, "Expected Ack after ADDBA Request");
355  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 1, "Expected a transmission in BSS 1");
356  psduIt++;
357 
358  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsAck(), true, "Expected Ack after ADDBA Response");
359  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 1, "Expected a transmission in BSS 1");
360  psduIt++;
361 
362  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsQosData(), true, "Expected a QoS data frame");
363  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 1, "Expected a transmission in BSS 1");
364  NS_TEST_EXPECT_MSG_EQ(psduIt->nMpdus, 2, "Expected an A-MPDU of 2 MPDUs after Block Ack");
366  psduIt->txVector.GetChannelWidth(),
367  StaticCast<WifiNetDevice>(m_apDevices.Get(1))->GetPhy()->GetChannelWidth(),
368  "Expected a transmission on the whole channel width");
369  psduIt++;
370 
371  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsBlockAck(), true, "Expected Block Ack after data frame");
372  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 1, "Expected a transmission in BSS 1");
373  psduIt++;
374 
375  // after some time, we have another A-MPDU transmitted in BSS 1
376  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsQosData(), true, "Expected a QoS data frame");
377  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 1, "Expected a transmission in BSS 1");
378  NS_TEST_EXPECT_MSG_EQ(psduIt->nMpdus,
379  +m_txPkts,
380  "Expected an A-MPDU of " << +m_txPkts << " MPDUs");
382  psduIt->txVector.GetChannelWidth(),
383  StaticCast<WifiNetDevice>(m_apDevices.Get(1))->GetPhy()->GetChannelWidth(),
384  "Expected a transmission on the whole channel width");
385  psduIt++;
386 
387  // we expect that the AP of BSS 0 starts transmitting while the AP of BSS 1 is transmitting
388  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsQosData(), true, "Expected a QoS data frame");
389  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 0, "Expected a transmission in BSS 0");
390  NS_TEST_EXPECT_MSG_EQ(psduIt->nMpdus,
391  +m_txPkts,
392  "Expected an A-MPDU of " << +m_txPkts << " MPDUs");
393  NS_TEST_EXPECT_MSG_EQ(psduIt->txVector.GetChannelWidth(),
394  m_bss0Width,
395  "Unexpected transmission width");
396  NS_TEST_EXPECT_MSG_LT(psduIt->txStart,
397  std::prev(psduIt)->txStart + std::prev(psduIt)->txDuration,
398  "AP 0 is expected to transmit before the end of transmission of AP 1");
399  psduIt++;
400 
401  // receive a Block Ack in BSS 1 and then a Block Ack in BSS 0
402  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsBlockAck(), true, "Expected Block Ack after data frame");
403  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 1, "Expected a transmission in BSS 1");
404  psduIt++;
405 
406  NS_TEST_EXPECT_MSG_EQ(psduIt->header.IsBlockAck(), true, "Expected Block Ack after data frame");
407  NS_TEST_EXPECT_MSG_EQ(+psduIt->bss, 0, "Expected a transmission in BSS 0");
408  psduIt++;
409 
410  // each application server (on STAs) received 2 packets right after Block Ack
411  // agreement establishment and m_txPkts packets afterwards
413  2 + m_txPkts,
414  "Unexpected number of packets received by STA 0");
416  2 + m_txPkts,
417  "Unexpected number of packets received by STA 1");
418 }
419 
427 {
428  public:
430 };
431 
433  : TestSuite("wifi-dynamic-bw-op", UNIT)
434 {
445  AddTestCase(new WifiUseAvailBwTest({"{54, 40, BAND_5GHZ, 1}", "{52, 20, BAND_5GHZ, 0}"}, 20),
446  TestCase::QUICK);
459  AddTestCase(new WifiUseAvailBwTest({"{58, 80, BAND_5GHZ, 0}", "{62, 40, BAND_5GHZ, 1}"}, 40),
460  TestCase::QUICK);
473  AddTestCase(new WifiUseAvailBwTest({"{50, 160, BAND_5GHZ, 5}", "{42, 80, BAND_5GHZ, 2}"}, 80),
474  TestCase::QUICK);
475 }
476 
wifi dynamic bandwidth operation Test Suite
Two BSSes, each with one AP and one non-AP STA, are configured to operate on different channels.
void Transmit(uint8_t bss, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when a PHY receives a PSDU to transmit.
std::vector< std::string > m_channelStr
channel setting strings
std::array< uint8_t, 2 > m_rcvPkts
number of packets received by the stations
std::vector< FrameInfo > m_txPsdus
transmitted PSDUs
std::array< PacketSocketAddress, 2 > m_sockets
packet sockets for the two BSSes
void L7Receive(uint8_t bss, Ptr< const Packet > p, const Address &addr)
Function to trace packets received by the server application in the given BSS.
uint16_t m_bss0Width
width (MHz) of the transmission in BSS 0 started when BSS 1 is transmitting
void DoRun() override
Implementation to actually run this TestCase.
uint8_t m_txPkts
TX packets per BSS (in addition to the two required to establish BA agreement)
void CheckResults()
Check correctness of transmitted frames.
NetDeviceContainer m_apDevices
container for AP's NetDevice
NetDeviceContainer m_staDevices
container for stations' NetDevices
WifiUseAvailBwTest(std::initializer_list< std::string > channelStr, uint16_t bss0Width)
Constructor.
a polymophic address class
Definition: address.h:101
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
Vector GetPosition() const
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of 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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
Implements the IEEE 802.11 MAC header.
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:950
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:790
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
@ WIFI_STANDARD_80211ax
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
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.
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...
Definition: callback.h:704
mac
Definition: third.py:92
wifi
Definition: third.py:95
mobility
Definition: third.py:105
wifiStaNodes
Definition: third.py:84
phy
Definition: third.py:89
Information about transmitted frames.
uint8_t bss
BSS the frame belongs to.
std::size_t nMpdus
number of MPDUs in the PSDU
WifiTxVector txVector
TX vector used to transmit the frame.
WifiMacHeader header
Frame MAC header.
uint32_t prev
static WifiDynamicBwOpTestSuite g_wifiDynamicBwOpTestSuite
the test suite