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