A Discrete-Event Network Simulator
API
wifi-txop-test.cc
Go to the documentation of this file.
1  /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/test.h"
22 #include "ns3/string.h"
23 #include "ns3/qos-utils.h"
24 #include "ns3/packet.h"
25 #include "ns3/wifi-net-device.h"
26 #include "ns3/wifi-mac-header.h"
27 #include "ns3/mobility-helper.h"
28 #include "ns3/spectrum-wifi-helper.h"
29 #include "ns3/single-model-spectrum-channel.h"
30 #include "ns3/packet-socket-server.h"
31 #include "ns3/packet-socket-client.h"
32 #include "ns3/packet-socket-helper.h"
33 #include "ns3/config.h"
34 #include "ns3/pointer.h"
35 #include "ns3/rng-seed-manager.h"
36 #include "ns3/wifi-psdu.h"
37 #include "ns3/wifi-ppdu.h"
38 #include "ns3/ap-wifi-mac.h"
39 
40 using namespace ns3;
41 
42 
51 class WifiTxopTest : public TestCase
52 {
53 public:
58  WifiTxopTest (bool pifsRecovery);
59  virtual ~WifiTxopTest ();
60 
67  void L7Receive (std::string context, Ptr<const Packet> p, const Address &addr);
75  void Transmit (std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
79  void CheckResults (void);
80 
81 private:
82  void DoRun (void) override;
83 
85  struct FrameInfo
86  {
91  };
92 
93  uint16_t m_nStations;
96  std::vector<FrameInfo> m_txPsdus;
98  uint8_t m_aifsn;
99  uint32_t m_cwMin;
100  uint16_t m_received;
102 };
103 
104 WifiTxopTest::WifiTxopTest (bool pifsRecovery)
105  : TestCase ("Check correct operation within TXOPs"),
106  m_nStations (3),
107  m_txopLimit (MicroSeconds (4768)),
108  m_received (0),
109  m_pifsRecovery (pifsRecovery)
110 {
111 }
112 
114 {
115 }
116 
117 void
118 WifiTxopTest::L7Receive (std::string context, Ptr<const Packet> p, const Address &addr)
119 {
120  if (p->GetSize () >= 500)
121  {
122  m_received++;
123  }
124 }
125 
126 void
127 WifiTxopTest::Transmit (std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
128 {
129  // Log all transmitted frames that are not beacon frames and have been transmitted
130  // after 400ms (so as to skip association requests/responses)
131  if (!psduMap.begin ()->second->GetHeader (0).IsBeacon ()
132  && Simulator::Now () > MilliSeconds (400))
133  {
134  m_txPsdus.push_back ({Simulator::Now (),
135  WifiPhy::CalculateTxDuration (psduMap, txVector, WIFI_PHY_BAND_5GHZ),
136  psduMap[SU_STA_ID]->GetHeader (0), txVector});
137  }
138 
139  // Print all the transmitted frames if the test is executed through test-runner
140  std::cout << Simulator::Now () << " " << psduMap.begin ()->second->GetHeader (0).GetTypeString ()
141  << " seq " << psduMap.begin ()->second->GetHeader (0).GetSequenceNumber ()
142  << " to " << psduMap.begin ()->second->GetAddr1 ()
143  << " TX duration " << WifiPhy::CalculateTxDuration (psduMap, txVector, WIFI_PHY_BAND_5GHZ)
144  << " duration/ID " << psduMap.begin ()->second->GetHeader (0).GetDuration () << std::endl;
145 }
146 
147 void
149 {
150  RngSeedManager::SetSeed (1);
151  RngSeedManager::SetRun (40);
152  int64_t streamNumber = 100;
153 
155  wifiApNode.Create (1);
156 
158  wifiStaNodes.Create (m_nStations);
159 
160  Ptr<SingleModelSpectrumChannel> spectrumChannel = CreateObject<SingleModelSpectrumChannel> ();
161  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
162  spectrumChannel->AddPropagationLossModel (lossModel);
163  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
164  spectrumChannel->SetPropagationDelayModel (delayModel);
165 
167  phy.SetChannel (spectrumChannel);
168 
169  Config::SetDefault ("ns3::QosFrameExchangeManager::PifsRecovery", BooleanValue (m_pifsRecovery));
170  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1900));
171 
173  wifi.SetStandard (WIFI_STANDARD_80211a);
174  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
175  "DataMode", StringValue ("OfdmRate12Mbps"),
176  "ControlMode", StringValue ("OfdmRate6Mbps"));
177 
179  mac.SetType ("ns3::StaWifiMac",
180  "QosSupported", BooleanValue (true),
181  "Ssid", SsidValue (Ssid ("non-existent-ssid")));
182 
183  m_staDevices = wifi.Install (phy, mac, wifiStaNodes);
184 
185  mac.SetType ("ns3::ApWifiMac",
186  "QosSupported", BooleanValue (true),
187  "Ssid", SsidValue (Ssid ("wifi-txop-ssid")),
188  "BeaconInterval", TimeValue (MicroSeconds (102400)),
189  "EnableBeaconJitter", BooleanValue (false));
190 
191  m_apDevices = wifi.Install (phy, mac, wifiApNode);
192 
193  // schedule association requests at different times
194  Time init = MilliSeconds (100);
195  Ptr<WifiNetDevice> dev;
196 
197  for (uint16_t i = 0; i < m_nStations; i++)
198  {
199  dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (i));
200  Simulator::Schedule (init + i * MicroSeconds (102400), &WifiMac::SetSsid,
201  dev->GetMac (), Ssid ("wifi-txop-ssid"));
202  }
203 
204  // Assign fixed streams to random variables in use
205  wifi.AssignStreams (m_apDevices, streamNumber);
206 
208  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
209 
210  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
211  positionAlloc->Add (Vector (1.0, 0.0, 0.0));
212  positionAlloc->Add (Vector (0.0, 1.0, 0.0));
213  positionAlloc->Add (Vector (-1.0, 0.0, 0.0));
214  mobility.SetPositionAllocator (positionAlloc);
215 
216  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
217  mobility.Install (wifiApNode);
218  mobility.Install (wifiStaNodes);
219 
220  // set the TXOP limit on BE AC
221  dev = DynamicCast<WifiNetDevice> (m_apDevices.Get (0));
222  PointerValue ptr;
223  dev->GetMac ()->GetAttribute ("BE_Txop", ptr);
224  ptr.Get<QosTxop> ()->SetTxopLimit (m_txopLimit);
225  m_aifsn = ptr.Get<QosTxop> ()->GetAifsn ();
226  m_cwMin = ptr.Get<QosTxop> ()->GetMinCw ();
227 
228  PacketSocketHelper packetSocket;
229  packetSocket.Install (wifiApNode);
230  packetSocket.Install (wifiStaNodes);
231 
232  // DL frames
233  for (uint16_t i = 0; i < m_nStations; i++)
234  {
235  PacketSocketAddress socket;
236  socket.SetSingleDevice (m_apDevices.Get (0)->GetIfIndex ());
237  socket.SetPhysicalAddress (m_staDevices.Get (i)->GetAddress ());
238  socket.SetProtocol (1);
239 
240  // Send one QoS data frame (not protected by RTS/CTS) to each station
241  Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient> ();
242  client1->SetAttribute ("PacketSize", UintegerValue (500));
243  client1->SetAttribute ("MaxPackets", UintegerValue (1));
244  client1->SetAttribute ("Interval", TimeValue (MicroSeconds (1)));
245  client1->SetRemote (socket);
246  wifiApNode.Get (0)->AddApplication (client1);
247  client1->SetStartTime (MilliSeconds (410));
248  client1->SetStopTime (Seconds (1.0));
249 
250  // Send one QoS data frame (protected by RTS/CTS) to each station
251  Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient> ();
252  client2->SetAttribute ("PacketSize", UintegerValue (2000));
253  client2->SetAttribute ("MaxPackets", UintegerValue (1));
254  client2->SetAttribute ("Interval", TimeValue (MicroSeconds (1)));
255  client2->SetRemote (socket);
256  wifiApNode.Get (0)->AddApplication (client2);
257  client2->SetStartTime (MilliSeconds (520));
258  client2->SetStopTime (Seconds (1.0));
259 
260  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
261  server->SetLocal (socket);
262  wifiStaNodes.Get (i)->AddApplication (server);
263  server->SetStartTime (Seconds (0.0));
264  server->SetStopTime (Seconds (1.0));
265  }
266 
267  // The AP does not correctly receive the Ack sent in response to the QoS
268  // data frame sent to the first station
269  Ptr<ReceiveListErrorModel> apPem = CreateObject<ReceiveListErrorModel> ();
270  apPem->SetList ({6});
271  dev = DynamicCast<WifiNetDevice> (m_apDevices.Get (0));
272  dev->GetMac ()->GetWifiPhy ()->SetPostReceptionErrorModel (apPem);
273 
274  // The second station does not correctly receive the first QoS
275  // data frame sent by the AP
276  Ptr<ReceiveListErrorModel> sta2Pem = CreateObject<ReceiveListErrorModel> ();
277  sta2Pem->SetList ({19});
278  dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (1));
279  dev->GetMac ()->GetWifiPhy ()->SetPostReceptionErrorModel (sta2Pem);
280 
281  // UL Traffic (the first station sends one frame to the AP)
282  {
283  PacketSocketAddress socket;
284  socket.SetSingleDevice (m_staDevices.Get (0)->GetIfIndex ());
285  socket.SetPhysicalAddress (m_apDevices.Get (0)->GetAddress ());
286  socket.SetProtocol (1);
287 
288  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
289  client->SetAttribute ("PacketSize", UintegerValue (1500));
290  client->SetAttribute ("MaxPackets", UintegerValue (1));
291  client->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
292  client->SetRemote (socket);
293  wifiStaNodes.Get (0)->AddApplication (client);
294  client->SetStartTime (MilliSeconds (412));
295  client->SetStopTime (Seconds (1.0));
296 
297  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
298  server->SetLocal (socket);
299  wifiApNode.Get (0)->AddApplication (server);
300  server->SetStartTime (Seconds (0.0));
301  server->SetStopTime (Seconds (1.0));
302  }
303 
304  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSocketServer/Rx",
306  // Trace PSDUs passed to the PHY on all devices
307  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
309 
310  Simulator::Stop (Seconds (1));
311  Simulator::Run ();
312 
313  CheckResults ();
314 
315  Simulator::Destroy ();
316 }
317 
318 void
320 {
321  Time tEnd, // TX end for a frame
322  tStart, // TX start fot the next frame
323  txopStart, // TXOP start time
324  tolerance = NanoSeconds (50), // due to propagation delay
325  sifs = DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetPhy ()->GetSifs (),
326  slot = DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetPhy ()->GetSlot (),
327  navEnd;
328 
329  // lambda to round Duration/ID (in microseconds) up to the next higher integer
330  auto RoundDurationId = [] (Time t)
331  {
332  return MicroSeconds (ceil (static_cast<double> (t.GetNanoSeconds ()) / 1000));
333  };
334 
335  /*
336  * Verify the different behavior followed when an initial/non-initial frame of a TXOP
337  * fails. Also, verify that a CF-end frame is sent if enough time remains in the TXOP.
338  * The destination of failed frames is put in square brackets below.
339  *
340  * |---NAV-----till end TXOP--------->|
341  * | |----NAV--till end TXOP---->|
342  * | | |---------------------------NAV---------------------------------->|
343  * | | | |--------------------------NAV---------------------------->|
344  * | | | | |------------------------NAV----------------------->|
345  * | | | | | |-------------NAV--------------->|
346  * Start| | Start| | | | |----------NAV----------->|
347  * TXOP | | TXOP | | | Ack | | |-------NAV------->|
348  * | | | | | | | Timeout | | | |---NAV---->|
349  * |---| |---|-backoff->|---| |---| |---| |-PIFS or->|---| |---| |---| |---| |-----|
350  * |QoS| |Ack| |QoS| |Ack| |QoS| |-backoff->|QoS| |Ack| |QoS| |Ack| |CFend|
351  * ----------------------------------------------------------------------------------------------------
352  * From: AP STA1 AP STA1 AP AP STA2 AP STA3 AP
353  * To: STA1 [AP] STA1 AP [STA2] STA2 AP STA3 AP all
354  */
355 
356  NS_TEST_EXPECT_MSG_EQ (m_txPsdus.size (), 25, "Expected 25 transmitted frames");
357 
358  // the first frame sent after 400ms is a QoS data frame sent by the AP to STA1
359  txopStart = m_txPsdus[0].txStart;
360 
361  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[0].header.IsQosData (), true,
362  "Expected a QoS data frame");
363  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[0].header.GetAddr1 (),
364  DynamicCast<WifiNetDevice> (m_staDevices.Get (0))->GetMac ()->GetAddress (),
365  "Expected a frame sent by the AP to the first station");
366  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[0].header.GetDuration (),
367  RoundDurationId (m_txopLimit - m_txPsdus[0].txDuration),
368  "Duration/ID of the first frame must cover the whole TXOP");
369 
370  // a Normal Ack is sent by STA1
371  tEnd = m_txPsdus[0].txStart + m_txPsdus[0].txDuration;
372  tStart = m_txPsdus[1].txStart;
373 
374  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the first frame sent too early");
375  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the first frame sent too late");
376  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[1].header.IsAck (), true, "Expected a Normal Ack");
377  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[1].header.GetAddr1 (),
378  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
379  "Expected a Normal Ack sent to the AP");
380  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[1].header.GetDuration (),
381  RoundDurationId (m_txPsdus[0].header.GetDuration () - sifs - m_txPsdus[1].txDuration),
382  "Duration/ID of the Ack must be derived from that of the first frame");
383 
384  // the AP receives a corrupted Ack in response to the frame it sent, which is the initial
385  // frame of a TXOP. Hence, the TXOP is terminated and the AP retransmits the frame after
386  // invoking the backoff
387  txopStart = m_txPsdus[2].txStart;
388 
389  tEnd = m_txPsdus[1].txStart + m_txPsdus[1].txDuration;
390  tStart = m_txPsdus[2].txStart;
391 
392  NS_TEST_EXPECT_MSG_GT_OR_EQ (tStart - tEnd, sifs + m_aifsn * slot,
393  "Less than AIFS elapsed between AckTimeout and the next TXOP start");
394  NS_TEST_EXPECT_MSG_LT_OR_EQ (tStart - tEnd, sifs + m_aifsn * slot + (2 * (m_cwMin + 1) - 1) * slot,
395  "More than AIFS+BO elapsed between AckTimeout and the next TXOP start");
396  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[2].header.IsQosData (), true,
397  "Expected to retransmit a QoS data frame");
398  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[2].header.GetAddr1 (),
399  DynamicCast<WifiNetDevice> (m_staDevices.Get (0))->GetMac ()->GetAddress (),
400  "Expected to retransmit a frame to the first station");
401  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[2].header.GetDuration (),
402  RoundDurationId (m_txopLimit - m_txPsdus[2].txDuration),
403  "Duration/ID of the retransmitted frame must cover the whole TXOP");
404 
405  // a Normal Ack is then sent by STA1
406  tEnd = m_txPsdus[2].txStart + m_txPsdus[2].txDuration;
407  tStart = m_txPsdus[3].txStart;
408 
409  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the first frame sent too early");
410  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the first frame sent too late");
411  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[3].header.IsAck (), true, "Expected a Normal Ack");
412  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[3].header.GetAddr1 (),
413  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
414  "Expected a Normal Ack sent to the AP");
415  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[3].header.GetDuration (),
416  RoundDurationId (m_txPsdus[2].header.GetDuration () - sifs - m_txPsdus[3].txDuration),
417  "Duration/ID of the Ack must be derived from that of the previous frame");
418 
419  // the AP sends a frame to STA2
420  tEnd = m_txPsdus[3].txStart + m_txPsdus[3].txDuration;
421  tStart = m_txPsdus[4].txStart;
422 
423  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Second frame sent too early");
424  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Second frame sent too late");
425  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[4].header.IsQosData (), true,
426  "Expected a QoS data frame");
427  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[4].header.GetAddr1 (),
428  DynamicCast<WifiNetDevice> (m_staDevices.Get (1))->GetMac ()->GetAddress (),
429  "Expected a frame sent by the AP to the second station");
430  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[4].header.GetDuration (),
431  RoundDurationId (m_txopLimit - (m_txPsdus[4].txStart - txopStart) - m_txPsdus[4].txDuration),
432  "Duration/ID of the second frame does not cover the remaining TXOP");
433 
434  // STA2 receives a corrupted frame and hence it does not send the Ack. When the AckTimeout
435  // expires, the AP performs PIFS recovery or invoke backoff, without terminating the TXOP,
436  // because a non-initial frame of the TXOP failed
437  tEnd = m_txPsdus[4].txStart + m_txPsdus[4].txDuration
438  + sifs + slot + WifiPhy::CalculatePhyPreambleAndHeaderDuration (m_txPsdus[4].txVector); // AckTimeout
439  tStart = m_txPsdus[5].txStart;
440 
441  if (m_pifsRecovery)
442  {
443  NS_TEST_EXPECT_MSG_EQ (tEnd + sifs + slot, tStart, "Second frame must have been sent after a PIFS");
444  }
445  else
446  {
447  NS_TEST_EXPECT_MSG_GT_OR_EQ (tStart - tEnd, sifs + m_aifsn * slot,
448  "Less than AIFS elapsed between AckTimeout and the next transmission");
449  NS_TEST_EXPECT_MSG_LT_OR_EQ (tStart - tEnd, sifs + m_aifsn * slot + (2 * (m_cwMin + 1) - 1) * slot,
450  "More than AIFS+BO elapsed between AckTimeout and the next TXOP start");
451  }
452  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[5].header.IsQosData (), true,
453  "Expected a QoS data frame");
454  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[5].header.GetAddr1 (),
455  DynamicCast<WifiNetDevice> (m_staDevices.Get (1))->GetMac ()->GetAddress (),
456  "Expected a frame sent by the AP to the second station");
457  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[5].header.GetDuration (),
458  RoundDurationId (m_txopLimit - (m_txPsdus[5].txStart - txopStart) - m_txPsdus[5].txDuration),
459  "Duration/ID of the second frame does not cover the remaining TXOP");
460 
461  // a Normal Ack is then sent by STA2
462  tEnd = m_txPsdus[5].txStart + m_txPsdus[5].txDuration;
463  tStart = m_txPsdus[6].txStart;
464 
465  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the second frame sent too early");
466  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the second frame sent too late");
467  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[6].header.IsAck (), true, "Expected a Normal Ack");
468  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[6].header.GetAddr1 (),
469  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
470  "Expected a Normal Ack sent to the AP");
471  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[6].header.GetDuration (),
472  RoundDurationId (m_txPsdus[5].header.GetDuration () - sifs - m_txPsdus[6].txDuration),
473  "Duration/ID of the Ack must be derived from that of the previous frame");
474 
475  // the AP sends a frame to STA3
476  tEnd = m_txPsdus[6].txStart + m_txPsdus[6].txDuration;
477  tStart = m_txPsdus[7].txStart;
478 
479  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Third frame sent too early");
480  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Third frame sent too late");
481  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[7].header.IsQosData (), true,
482  "Expected a QoS data frame");
483  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[7].header.GetAddr1 (),
484  DynamicCast<WifiNetDevice> (m_staDevices.Get (2))->GetMac ()->GetAddress (),
485  "Expected a frame sent by the AP to the third station");
486  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[7].header.GetDuration (),
487  RoundDurationId (m_txopLimit - (m_txPsdus[7].txStart - txopStart) - m_txPsdus[7].txDuration),
488  "Duration/ID of the third frame does not cover the remaining TXOP");
489 
490  // a Normal Ack is then sent by STA3
491  tEnd = m_txPsdus[7].txStart + m_txPsdus[7].txDuration;
492  tStart = m_txPsdus[8].txStart;
493 
494  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the third frame sent too early");
495  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the third frame sent too late");
496  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[8].header.IsAck (), true, "Expected a Normal Ack");
497  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[8].header.GetAddr1 (),
498  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
499  "Expected a Normal Ack sent to the AP");
500  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[8].header.GetDuration (),
501  RoundDurationId (m_txPsdus[7].header.GetDuration () - sifs - m_txPsdus[8].txDuration),
502  "Duration/ID of the Ack must be derived from that of the previous frame");
503 
504  // the TXOP limit is such that enough time for sending a CF-End frame remains
505  tEnd = m_txPsdus[8].txStart + m_txPsdus[8].txDuration;
506  tStart = m_txPsdus[9].txStart;
507 
508  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "CF-End sent too early");
509  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "CF-End sent too late");
510  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[9].header.IsCfEnd (), true, "Expected a CF-End frame");
511  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[9].header.GetDuration (), Seconds (0),
512  "Duration/ID must be set to 0 for CF-End frames");
513 
514  // the CF-End frame resets the NAV on STA1, which can now transmit
515  tEnd = m_txPsdus[9].txStart + m_txPsdus[9].txDuration;
516  tStart = m_txPsdus[10].txStart;
517 
518  NS_TEST_EXPECT_MSG_GT_OR_EQ (tStart - tEnd, sifs + m_aifsn * slot,
519  "Less than AIFS elapsed between two TXOPs");
520  NS_TEST_EXPECT_MSG_LT_OR_EQ (tStart - tEnd, sifs + m_aifsn * slot + m_cwMin * slot + tolerance,
521  "More than AIFS+BO elapsed between two TXOPs");
522  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[10].header.IsQosData (), true,
523  "Expected a QoS data frame");
524  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[10].header.GetAddr1 (),
525  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
526  "Expected a frame sent by the first station to the AP");
527  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[10].header.GetDuration (),
528  RoundDurationId (m_txopLimit - m_txPsdus[10].txDuration),
529  "Duration/ID of the frame sent by the first station does not cover the remaining TXOP");
530 
531  // a Normal Ack is then sent by the AP
532  tEnd = m_txPsdus[10].txStart + m_txPsdus[10].txDuration;
533  tStart = m_txPsdus[11].txStart;
534 
535  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack sent too early");
536  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack sent too late");
537  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[11].header.IsAck (), true, "Expected a Normal Ack");
538  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[11].header.GetAddr1 (),
539  DynamicCast<WifiNetDevice> (m_staDevices.Get (0))->GetMac ()->GetAddress (),
540  "Expected a Normal Ack sent to the first station");
541  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[11].header.GetDuration (),
542  RoundDurationId (m_txPsdus[10].header.GetDuration () - sifs - m_txPsdus[11].txDuration),
543  "Duration/ID of the Ack must be derived from that of the previous frame");
544 
545  // the TXOP limit is such that enough time for sending a CF-End frame remains
546  tEnd = m_txPsdus[11].txStart + m_txPsdus[11].txDuration;
547  tStart = m_txPsdus[12].txStart;
548 
549  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "CF-End sent too early");
550  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "CF-End sent too late");
551  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[12].header.IsCfEnd (), true, "Expected a CF-End frame");
552  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[12].header.GetDuration (), Seconds (0),
553  "Duration/ID must be set to 0 for CF-End frames");
554 
555 
556  /*
557  * Verify that the Duration/ID of RTS/CTS frames is set correctly, that the TXOP holder is
558  * kept and allows stations to ignore NAV properly and that the CF-End Frame is not sent if
559  * not enough time remains
560  *
561  * |---------------------------------------------NAV---------------------------------->|
562  * | |-----------------------------------------NAV------------------------------->|
563  * | | |-------------------------------------NAV---------------------------->|
564  * | | | |---------------------------------NAV------------------------->|
565  * | | | | |-----------------------------NAV---------------------->|
566  * | | | | | |-------------------------NAV------------------->|
567  * | | | | | | |---------------------NAV---------------->|
568  * | | | | | | | |-----------------NAV------------->|
569  * | | | | | | | | |-------------NAV---------->|
570  * | | | | | | | | | |---------NAV------->|
571  * | | | | | | | | | | |-----NAV---->|
572  * | | | | | | | | | | | |-NAV->|
573  * |---| |---| |---| |---| |---| |---| |---| |---| |---| |---| |---| |---|
574  * |RTS| |CTS| |QoS| |Ack| |RTS| |CTS| |QoS| |Ack| |RTS| |CTS| |QoS| |Ack|
575  * ----------------------------------------------------------------------------------------------------
576  * From: AP STA1 AP STA1 AP STA2 AP STA2 AP STA3 AP STA3
577  * To: STA1 AP STA1 AP STA2 AP STA2 AP STA3 AP STA3 AP
578  */
579 
580  // the first frame is an RTS frame sent by the AP to STA1
581  txopStart = m_txPsdus[13].txStart;
582 
583  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[13].header.IsRts (), true,
584  "Expected an RTS frame");
585  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[13].header.GetAddr1 (),
586  DynamicCast<WifiNetDevice> (m_staDevices.Get (0))->GetMac ()->GetAddress (),
587  "Expected an RTS frame sent by the AP to the first station");
588  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[13].header.GetDuration (),
589  RoundDurationId (m_txopLimit - m_txPsdus[13].txDuration),
590  "Duration/ID of the first RTS frame must cover the whole TXOP");
591 
592  // a CTS is sent by STA1
593  tEnd = m_txPsdus[13].txStart + m_txPsdus[13].txDuration;
594  tStart = m_txPsdus[14].txStart;
595 
596  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "CTS in response to the first RTS frame sent too early");
597  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "CTS in response to the first RTS frame sent too late");
598  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[14].header.IsCts (), true, "Expected a CTS");
599  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[14].header.GetAddr1 (),
600  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
601  "Expected a CTS frame sent to the AP");
602  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[14].header.GetDuration (),
603  RoundDurationId (m_txPsdus[13].header.GetDuration () - sifs - m_txPsdus[14].txDuration),
604  "Duration/ID of the CTS frame must be derived from that of the RTS frame");
605 
606  // the AP sends a frame to STA1
607  tEnd = m_txPsdus[14].txStart + m_txPsdus[14].txDuration;
608  tStart = m_txPsdus[15].txStart;
609 
610  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "First QoS data frame sent too early");
611  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "First QoS data frame sent too late");
612  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[15].header.IsQosData (), true,
613  "Expected a QoS data frame");
614  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[15].header.GetAddr1 (),
615  DynamicCast<WifiNetDevice> (m_staDevices.Get (0))->GetMac ()->GetAddress (),
616  "Expected a frame sent by the AP to the first station");
617  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[15].header.GetDuration (),
618  RoundDurationId (m_txopLimit - (m_txPsdus[15].txStart - txopStart) - m_txPsdus[15].txDuration),
619  "Duration/ID of the first QoS data frame does not cover the remaining TXOP");
620 
621  // a Normal Ack is then sent by STA1
622  tEnd = m_txPsdus[15].txStart + m_txPsdus[15].txDuration;
623  tStart = m_txPsdus[16].txStart;
624 
625  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the first QoS data frame sent too early");
626  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the first QoS data frame sent too late");
627  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[16].header.IsAck (), true, "Expected a Normal Ack");
628  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[16].header.GetAddr1 (),
629  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
630  "Expected a Normal Ack sent to the AP");
631  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[16].header.GetDuration (),
632  RoundDurationId (m_txPsdus[15].header.GetDuration () - sifs - m_txPsdus[16].txDuration),
633  "Duration/ID of the Ack must be derived from that of the previous frame");
634 
635  // An RTS frame is sent by the AP to STA2
636  tEnd = m_txPsdus[16].txStart + m_txPsdus[16].txDuration;
637  tStart = m_txPsdus[17].txStart;
638 
639  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Second RTS frame sent too early");
640  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Second RTS frame sent too late");
641  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[17].header.IsRts (), true,
642  "Expected an RTS frame");
643  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[17].header.GetAddr1 (),
644  DynamicCast<WifiNetDevice> (m_staDevices.Get (1))->GetMac ()->GetAddress (),
645  "Expected an RTS frame sent by the AP to the second station");
646  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[17].header.GetDuration (),
647  RoundDurationId (m_txopLimit - (m_txPsdus[17].txStart - txopStart) - m_txPsdus[17].txDuration),
648  "Duration/ID of the second RTS frame must cover the whole TXOP");
649 
650  // a CTS is sent by STA2 (which ignores the NAV)
651  tEnd = m_txPsdus[17].txStart + m_txPsdus[17].txDuration;
652  tStart = m_txPsdus[18].txStart;
653 
654  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "CTS in response to the second RTS frame sent too early");
655  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "CTS in response to the second RTS frame sent too late");
656  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[18].header.IsCts (), true, "Expected a CTS");
657  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[18].header.GetAddr1 (),
658  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
659  "Expected a CTS frame sent to the AP");
660  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[18].header.GetDuration (),
661  RoundDurationId (m_txPsdus[17].header.GetDuration () - sifs - m_txPsdus[18].txDuration),
662  "Duration/ID of the CTS frame must be derived from that of the RTS frame");
663 
664  // the AP sends a frame to STA2
665  tEnd = m_txPsdus[18].txStart + m_txPsdus[18].txDuration;
666  tStart = m_txPsdus[19].txStart;
667 
668  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Second QoS data frame sent too early");
669  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Second QoS data frame sent too late");
670  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[19].header.IsQosData (), true,
671  "Expected a QoS data frame");
672  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[19].header.GetAddr1 (),
673  DynamicCast<WifiNetDevice> (m_staDevices.Get (1))->GetMac ()->GetAddress (),
674  "Expected a frame sent by the AP to the second station");
675  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[19].header.GetDuration (),
676  RoundDurationId (m_txopLimit - (m_txPsdus[19].txStart - txopStart) - m_txPsdus[19].txDuration),
677  "Duration/ID of the second QoS data frame does not cover the remaining TXOP");
678 
679  // a Normal Ack is then sent by STA2
680  tEnd = m_txPsdus[19].txStart + m_txPsdus[19].txDuration;
681  tStart = m_txPsdus[20].txStart;
682 
683  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the second QoS data frame sent too early");
684  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the second QoS data frame sent too late");
685  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[20].header.IsAck (), true, "Expected a Normal Ack");
686  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[20].header.GetAddr1 (),
687  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
688  "Expected a Normal Ack sent to the AP");
689  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[20].header.GetDuration (),
690  RoundDurationId (m_txPsdus[19].header.GetDuration () - sifs - m_txPsdus[20].txDuration),
691  "Duration/ID of the Ack must be derived from that of the previous frame");
692 
693  // An RTS frame is sent by the AP to STA3
694  tEnd = m_txPsdus[20].txStart + m_txPsdus[20].txDuration;
695  tStart = m_txPsdus[21].txStart;
696 
697  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Third RTS frame sent too early");
698  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Third RTS frame sent too late");
699  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[21].header.IsRts (), true,
700  "Expected an RTS frame");
701  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[21].header.GetAddr1 (),
702  DynamicCast<WifiNetDevice> (m_staDevices.Get (2))->GetMac ()->GetAddress (),
703  "Expected an RTS frame sent by the AP to the third station");
704  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[21].header.GetDuration (),
705  RoundDurationId (m_txopLimit - (m_txPsdus[21].txStart - txopStart) - m_txPsdus[21].txDuration),
706  "Duration/ID of the third RTS frame must cover the whole TXOP");
707 
708  // a CTS is sent by STA3 (which ignores the NAV)
709  tEnd = m_txPsdus[21].txStart + m_txPsdus[21].txDuration;
710  tStart = m_txPsdus[22].txStart;
711 
712  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "CTS in response to the third RTS frame sent too early");
713  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "CTS in response to the third RTS frame sent too late");
714  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[22].header.IsCts (), true, "Expected a CTS");
715  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[22].header.GetAddr1 (),
716  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
717  "Expected a CTS frame sent to the AP");
718  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[22].header.GetDuration (),
719  RoundDurationId (m_txPsdus[21].header.GetDuration () - sifs - m_txPsdus[22].txDuration),
720  "Duration/ID of the CTS frame must be derived from that of the RTS frame");
721 
722  // the AP sends a frame to STA3
723  tEnd = m_txPsdus[22].txStart + m_txPsdus[22].txDuration;
724  tStart = m_txPsdus[23].txStart;
725 
726  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Third QoS data frame sent too early");
727  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Third QoS data frame sent too late");
728  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[23].header.IsQosData (), true,
729  "Expected a QoS data frame");
730  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[23].header.GetAddr1 (),
731  DynamicCast<WifiNetDevice> (m_staDevices.Get (2))->GetMac ()->GetAddress (),
732  "Expected a frame sent by the AP to the third station");
733  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[23].header.GetDuration (),
734  RoundDurationId (m_txopLimit - (m_txPsdus[23].txStart - txopStart) - m_txPsdus[23].txDuration),
735  "Duration/ID of the third QoS data frame does not cover the remaining TXOP");
736 
737  // a Normal Ack is then sent by STA3
738  tEnd = m_txPsdus[23].txStart + m_txPsdus[23].txDuration;
739  tStart = m_txPsdus[24].txStart;
740 
741  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Ack in response to the third QoS data frame sent too early");
742  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Ack in response to the third QoS data frame sent too late");
743  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[24].header.IsAck (), true, "Expected a Normal Ack");
744  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[24].header.GetAddr1 (),
745  DynamicCast<WifiNetDevice> (m_apDevices.Get (0))->GetMac ()->GetAddress (),
746  "Expected a Normal Ack sent to the AP");
747  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[24].header.GetDuration (),
748  RoundDurationId (m_txPsdus[23].header.GetDuration () - sifs - m_txPsdus[24].txDuration),
749  "Duration/ID of the Ack must be derived from that of the previous frame");
750 
751  // there is no time remaining for sending a CF-End frame. This is verified by checking
752  // that 25 frames are transmitted (done at the beginning of this method)
753 
754  // 3 DL packets (without RTS/CTS), 1 UL packet and 3 DL packets (with RTS/CTS)
755  NS_TEST_EXPECT_MSG_EQ (m_received, 7, "Unexpected number of packets received");
756 }
757 
758 
766 {
767 public:
769 };
770 
772  : TestSuite ("wifi-txop", UNIT)
773 {
774  AddTestCase (new WifiTxopTest (true), TestCase::QUICK);
775  AddTestCase (new WifiTxopTest (false), TestCase::QUICK);
776 }
777 
Test TXOP rules.
void L7Receive(std::string context, Ptr< const Packet > p, const Address &addr)
Function to trace packets received by the server application.
bool m_pifsRecovery
whether to use PIFS recovery
NetDeviceContainer m_apDevices
container for AP's NetDevice
uint32_t m_cwMin
CWmin for BE.
virtual ~WifiTxopTest()
uint16_t m_received
number of packets received by the stations
uint16_t m_nStations
number of stations
uint8_t m_aifsn
AIFSN for BE.
Time m_txopLimit
TXOP limit.
void CheckResults(void)
Check correctness of transmitted frames.
std::vector< FrameInfo > m_txPsdus
transmitted PSDUs
void Transmit(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when PHY receives a PSDU to transmit.
NetDeviceContainer m_staDevices
container for stations' NetDevices
void DoRun(void) override
Implementation to actually run this TestCase.
WifiTxopTest(bool pifsRecovery)
Constructor.
wifi TXOP Test Suite
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
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.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
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.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get(void) const
Definition: pointer.h:201
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:75
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:1154
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1344
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
AttributeValue implementation for Time.
Definition: nstime.h:1353
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:327
Implements the IEEE 802.11 MAC header.
create MAC layers for a ns3::WifiNetDevice.
Ptr< WifiMac > GetMac(void) const
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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.
Definition: test.h:1109
#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.
Definition: test.h:922
#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:901
#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:283
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
@ WIFI_STANDARD_80211a
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
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, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
mac
Definition: third.py:99
wifi
Definition: third.py:96
wifiApNode
Definition: third.py:90
mobility
Definition: third.py:108
wifiStaNodes
Definition: third.py:88
phy
Definition: third.py:93
Information about transmitted frames.
WifiMacHeader header
Frame MAC header.
WifiTxVector txVector
TX vector used to transmit the frame.
Time txStart
Frame start TX time.
Time txDuration
Frame TX duration.
#define SU_STA_ID
Definition: wifi-mode.h:32
static WifiTxopTestSuite g_wifiTxopTestSuite
the test suite