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
42using namespace ns3;
43
44
53class WifiTxopTest : public TestCase
54{
55public:
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
83private:
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;
102 uint16_t m_received;
104};
105
106WifiTxopTest::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
119void
120WifiTxopTest::L7Receive (std::string context, Ptr<const Packet> p, const Address &addr)
121{
122 if (p->GetSize () >= 500)
123 {
124 m_received++;
125 }
126}
127
128void
129WifiTxopTest::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
149void
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);
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;
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
320void
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{
769public:
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.
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:323
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:96
wifi
Definition: third.py:99
wifiApNode
Definition: third.py:90
mobility
Definition: third.py:107
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