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 
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
std::vector< FrameInfo > m_txPsdus
transmitted PSDUs
NetDeviceContainer m_apDevices
container for AP&#39;s NetDevice
AttributeValue implementation for Boolean.
Definition: boolean.h:36
WifiTxVector txVector
TX vector used to transmit the frame.
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Hold variables of type string.
Definition: string.h:41
Time txDuration
Frame TX duration.
A suite of tests to run.
Definition: test.h:1343
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
an address for a packet socket
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
void CheckResults(void)
Check correctness of transmitted frames.
#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
bool m_pifsRecovery
whether to use PIFS recovery
The 5 GHz band.
Definition: wifi-phy-band.h:37
encapsulates test code
Definition: test.h:1153
void AddPropagationLossModel(Ptr< PropagationLossModel > loss)
Add the single-frequency propagation loss model to be used.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:326
void L7Receive(std::string context, Ptr< const Packet > p, const Address &addr)
Function to trace packets received by the server application.
Give ns3::PacketSocket powers to ns3::Node.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
#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
a polymophic address class
Definition: address.h:90
mobility
Definition: third.py:108
phy
Definition: third.py:93
WifiMacHeader header
Frame MAC header.
AttributeValue implementation for Time.
Definition: nstime.h:1353
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
Hold an unsigned integer type.
Definition: uinteger.h:44
holds a vector of ns3::NetDevice pointers
mac
Definition: third.py:99
wifiApNode
Definition: third.py:90
uint16_t m_received
number of packets received by the stations
wifi TXOP Test Suite
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
Test TXOP rules.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
keep track of a set of node pointers.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void DoRun(void) override
Implementation to actually run this TestCase.
void SetList(const std::list< uint32_t > &packetlist)
Definition: error-model.cc:520
create MAC layers for a ns3::WifiNetDevice.
WifiTxopTest(bool pifsRecovery)
Constructor.
virtual ~WifiTxopTest()
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
NetDeviceContainer m_staDevices
container for stations&#39; NetDevices
wifi
Definition: third.py:96
Helper class used to assign positions and mobility models to nodes.
Ptr< WifiMac > GetMac(void) const
Information about transmitted frames.
void SetRemote(PacketSocketAddress addr)
set the remote address and protocol to be used
void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
Set the propagation delay model to be used.
Time txStart
Frame start TX time.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
AttributeValue implementation for Ssid.
Definition: ssid.h:105
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
uint8_t m_aifsn
AIFSN for BE.
void SetProtocol(uint16_t protocol)
Set the protocol.
void Add(Vector v)
Add a position to the list of positions.
#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
uint16_t m_nStations
number of stations
Time m_txopLimit
TXOP limit.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
wifiStaNodes
Definition: third.py:88
static WifiTxopTestSuite g_wifiTxopTestSuite
the test suite
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
#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
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
#define SU_STA_ID
Definition: wifi-mode.h:32
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
void Transmit(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when PHY receives a PSDU to transmit.
Implements the IEEE 802.11 MAC header.
uint32_t m_cwMin
CWmin for BE.
Make it easy to create and manage PHY objects for the spectrum model.