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