A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
block-ack-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, 2010 MIRKO BANCHI
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mirko Banchi <mk.banchi@gmail.com>
7 */
8
9#include "ns3/ap-wifi-mac.h"
10#include "ns3/attribute-container.h"
11#include "ns3/boolean.h"
12#include "ns3/config.h"
13#include "ns3/ctrl-headers.h"
14#include "ns3/double.h"
15#include "ns3/frame-exchange-manager.h"
16#include "ns3/mac-rx-middle.h"
17#include "ns3/mobility-helper.h"
18#include "ns3/multi-model-spectrum-channel.h"
19#include "ns3/originator-block-ack-agreement.h"
20#include "ns3/packet-socket-client.h"
21#include "ns3/packet-socket-helper.h"
22#include "ns3/packet-socket-server.h"
23#include "ns3/packet.h"
24#include "ns3/pointer.h"
25#include "ns3/qos-txop.h"
26#include "ns3/qos-utils.h"
27#include "ns3/recipient-block-ack-agreement.h"
28#include "ns3/spectrum-wifi-helper.h"
29#include "ns3/string.h"
30#include "ns3/test.h"
31#include "ns3/wifi-default-ack-manager.h"
32#include "ns3/wifi-mac-header.h"
33#include "ns3/wifi-mac-queue.h"
34#include "ns3/wifi-mpdu.h"
35#include "ns3/wifi-net-device.h"
36#include "ns3/wifi-phy.h"
37#include "ns3/yans-wifi-helper.h"
38
39#include <list>
40
41using namespace ns3;
42
43NS_LOG_COMPONENT_DEFINE("WifiBlockAckTest");
44
45/**
46 * \ingroup wifi-test
47 * \ingroup tests
48 *
49 * \brief Packet Buffering Case A
50 *
51 * This simple test verifies the correctness of buffering for packets received
52 * under block ack. In order to completely understand this example is important to cite
53 * section 9.10.3 in IEEE802.11 standard:
54 *
55 * "[...] The sequence number space is considered divided into two parts, one of which
56 * is “old” and one of which is “new” by means of a boundary created by adding half the
57 * sequence number range to the current start of receive window (modulo 2^12)."
58 */
59//-------------------------------------------------------------------------------------
60
61/* ----- = old packets
62 * +++++ = new packets
63 *
64 * CASE A: startSeq < endSeq
65 * - - +
66 * initial buffer state: 0 16 56000
67 *
68 *
69 * 0 4095
70 * |------|++++++++++++++++|-----|
71 * ^ ^
72 * | startSeq | endSeq = 4000
73 *
74 * first received packet's sequence control = 64016 (seqNum = 4001, fragNum = 0) -
75 * second received packet's sequence control = 63984 (seqNum = 3999, fragNum = 0) +
76 * 4001 is older seq number so this packet should be inserted at the buffer's begin.
77 * 3999 is previous element of older of new packets: it should be inserted at the end of buffer.
78 *
79 * expected buffer state: 64016 0 16 56000 63984
80 *
81 */
83{
84 public:
86 ~PacketBufferingCaseA() override;
87
88 private:
89 void DoRun() override;
90 std::list<uint16_t> m_expectedBuffer; ///< expected test buffer
91};
92
94 : TestCase("Check correct order of buffering when startSequence < endSeq")
95{
96 m_expectedBuffer.push_back(64016);
97 m_expectedBuffer.push_back(0);
98 m_expectedBuffer.push_back(16);
99 m_expectedBuffer.push_back(56000);
100 m_expectedBuffer.push_back(63984);
101}
102
106
107void
109{
110 std::list<uint16_t> m_buffer;
111 std::list<uint16_t>::iterator i;
112 std::list<uint16_t>::iterator j;
113 m_buffer.push_back(0);
114 m_buffer.push_back(16);
115 m_buffer.push_back(56000);
116
117 uint16_t endSeq = 4000;
118
119 uint16_t receivedSeq = 4001 * 16;
120 uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
121 /* cycle to right position for this packet */
122 for (i = m_buffer.begin(); i != m_buffer.end(); i++)
123 {
124 if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
125 {
126 // position found
127 break;
128 }
129 }
130 m_buffer.insert(i, receivedSeq);
131
132 receivedSeq = 3999 * 16;
133 mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
134 /* cycle to right position for this packet */
135 for (i = m_buffer.begin(); i != m_buffer.end(); i++)
136 {
137 if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
138 {
139 // position found
140 break;
141 }
142 }
143 m_buffer.insert(i, receivedSeq);
144
145 for (i = m_buffer.begin(), j = m_expectedBuffer.begin(); i != m_buffer.end(); i++, j++)
146 {
147 NS_TEST_EXPECT_MSG_EQ(*i, *j, "error in buffer order");
148 }
149}
150
151/**
152 * \ingroup wifi-test
153 * \ingroup tests
154 *
155 * \brief Packet Buffering Case B
156 *
157 * ----- = old packets
158 * +++++ = new packets
159 *
160 * CASE B: startSeq > endSeq
161 * - + +
162 * initial buffer state: 256 64000 16
163 *
164 *
165 * 0 4095
166 * |++++++|----------------|++++++|
167 * ^ ^
168 * | endSeq = 10 | startSeq
169 *
170 * first received packet's sequence control = 240 (seqNum = 15, fragNum = 0) -
171 * second received packet's sequence control = 241 (seqNum = 15, fragNum = 1) -
172 * third received packet's sequence control = 64800 (seqNum = 4050, fragNum = 0) +
173 * 240 is an old packet should be inserted at the buffer's begin.
174 * 241 is an old packet: second segment of the above packet.
175 * 4050 is a new packet: it should be inserted between 64000 and 16.
176 *
177 * expected buffer state: 240 241 256 64000 64800 16
178 *
179 */
181{
182 public:
184 ~PacketBufferingCaseB() override;
185
186 private:
187 void DoRun() override;
188 std::list<uint16_t> m_expectedBuffer; ///< expected test buffer
189};
190
192 : TestCase("Check correct order of buffering when startSequence > endSeq")
193{
194 m_expectedBuffer.push_back(240);
195 m_expectedBuffer.push_back(241);
196 m_expectedBuffer.push_back(256);
197 m_expectedBuffer.push_back(64000);
198 m_expectedBuffer.push_back(64800);
199 m_expectedBuffer.push_back(16);
200}
201
205
206void
208{
209 std::list<uint16_t> m_buffer;
210 std::list<uint16_t>::iterator i;
211 std::list<uint16_t>::iterator j;
212 m_buffer.push_back(256);
213 m_buffer.push_back(64000);
214 m_buffer.push_back(16);
215
216 uint16_t endSeq = 10;
217
218 uint16_t receivedSeq = 15 * 16;
219 uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
220 /* cycle to right position for this packet */
221 for (i = m_buffer.begin(); i != m_buffer.end(); i++)
222 {
223 if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
224 {
225 // position found
226 break;
227 }
228 }
229 m_buffer.insert(i, receivedSeq);
230
231 receivedSeq = 15 * 16 + 1;
232 mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
233 /* cycle to right position for this packet */
234 for (i = m_buffer.begin(); i != m_buffer.end(); i++)
235 {
236 if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
237 {
238 // position found
239 break;
240 }
241 }
242 m_buffer.insert(i, receivedSeq);
243
244 receivedSeq = 4050 * 16;
245 mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
246 /* cycle to right position for this packet */
247 for (i = m_buffer.begin(); i != m_buffer.end(); i++)
248 {
249 if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
250 {
251 // position found
252 break;
253 }
254 }
255 m_buffer.insert(i, receivedSeq);
256
257 for (i = m_buffer.begin(), j = m_expectedBuffer.begin(); i != m_buffer.end(); i++, j++)
258 {
259 NS_TEST_EXPECT_MSG_EQ(*i, *j, "error in buffer order");
260 }
261}
262
263/**
264 * \ingroup wifi-test
265 * \ingroup tests
266 *
267 * \brief Test for the originator block ack window
268 */
270{
271 public:
273
274 private:
275 void DoRun() override;
276};
277
279 : TestCase("Check the correctness of the originator block ack window")
280{
281}
282
283void
285{
286 uint16_t winSize = 16;
287 uint16_t startingSeq = 4090;
288
289 OriginatorBlockAckAgreement agreement(Mac48Address("00:00:00:00:00:01"), 0);
290 agreement.SetBufferSize(winSize);
291 agreement.SetStartingSequence(startingSeq);
292 agreement.InitTxWindow();
293
294 NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.GetWinSize(), winSize, "Incorrect window size");
295 NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.GetWinStart(), startingSeq, "Incorrect winStart");
296 // check that all the elements in the window are cleared
297 for (uint16_t i = 0; i < winSize; i++)
298 {
300 false,
301 "Not all flags are cleared after initialization");
302 }
303
304 // Notify the acknowledgment of 5 packets
305 WifiMacHeader hdr;
308 uint16_t seqNumber = startingSeq;
309 mpdu->GetHeader().SetSequenceNumber(seqNumber);
310 agreement.NotifyAckedMpdu(mpdu);
311
312 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
313 agreement.NotifyAckedMpdu(mpdu);
314
315 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
316 agreement.NotifyAckedMpdu(mpdu);
317
318 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
319 agreement.NotifyAckedMpdu(mpdu);
320
321 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
322 agreement.NotifyAckedMpdu(mpdu);
323
324 // the current window must look like this:
325 //
326 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
327 // ^
328 // |
329 // HEAD
330
331 startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
333 startingSeq,
334 "Incorrect starting sequence after 5 acknowledgments");
335 for (uint16_t i = 0; i < winSize; i++)
336 {
338 false,
339 "Not all flags are cleared after 5 acknowledgments");
340 }
341
342 // the next MPDU is not acknowledged, hence the window is blocked while the
343 // subsequent 4 MPDUs are acknowledged
344 ++seqNumber %= SEQNO_SPACE_SIZE;
345 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
346 agreement.NotifyAckedMpdu(mpdu);
347
348 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
349 agreement.NotifyAckedMpdu(mpdu);
350
351 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
352 agreement.NotifyAckedMpdu(mpdu);
353
354 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
355 agreement.NotifyAckedMpdu(mpdu);
356
357 // the current window must look like this:
358 //
359 // |0|0|0|0|0|0|1|1|1|1|0|0|0|0|0|0|
360 // ^
361 // |
362 // HEAD
363
365 startingSeq,
366 "Incorrect starting sequence after 1 unacknowledged MPDU");
368 false,
369 "Incorrect flag after 1 unacknowledged MPDU");
371 true,
372 "Incorrect flag after 1 unacknowledged MPDU");
374 true,
375 "Incorrect flag after 1 unacknowledged MPDU");
377 true,
378 "Incorrect flag after 1 unacknowledged MPDU");
380 true,
381 "Incorrect flag after 1 unacknowledged MPDU");
382 for (uint16_t i = 5; i < winSize; i++)
383 {
385 false,
386 "Incorrect flag after 1 unacknowledged MPDU");
387 }
388
389 // the missing MPDU is now acknowledged; the window moves forward and the starting
390 // sequence number is the one of the first unacknowledged MPDU
391 mpdu->GetHeader().SetSequenceNumber(startingSeq);
392 agreement.NotifyAckedMpdu(mpdu);
393
394 // the current window must look like this:
395 //
396 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
397 // ^
398 // |
399 // HEAD
400
401 startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
403 startingSeq,
404 "Incorrect starting sequence after acknowledgment of missing MPDU");
405 for (uint16_t i = 0; i < winSize; i++)
406 {
408 false,
409 "Not all flags are cleared after acknowledgment of missing MPDU");
410 }
411
412 // Now, create a hole of 3 MPDUs before 4 acknowledged MPDUs, another hole of 2 MPDUs before 3
413 // acknowledged MPDUs
414 seqNumber = (seqNumber + 4) % SEQNO_SPACE_SIZE;
415 mpdu->GetHeader().SetSequenceNumber(seqNumber);
416 agreement.NotifyAckedMpdu(mpdu);
417
418 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
419 agreement.NotifyAckedMpdu(mpdu);
420
421 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
422 agreement.NotifyAckedMpdu(mpdu);
423
424 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
425 agreement.NotifyAckedMpdu(mpdu);
426
427 seqNumber = (seqNumber + 3) % SEQNO_SPACE_SIZE;
428 mpdu->GetHeader().SetSequenceNumber(seqNumber);
429 agreement.NotifyAckedMpdu(mpdu);
430
431 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
432 agreement.NotifyAckedMpdu(mpdu);
433
434 mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
435 agreement.NotifyAckedMpdu(mpdu);
436
437 // the current window must look like this:
438 //
439 // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
440 // ^
441 // |
442 // HEAD
443
445 startingSeq,
446 "Incorrect starting sequence after 3 unacknowledged MPDUs");
448 false,
449 "Incorrect flag after 3 unacknowledged MPDUs");
451 false,
452 "Incorrect flag after 3 unacknowledged MPDUs");
454 false,
455 "Incorrect flag after 3 unacknowledged MPDUs");
457 true,
458 "Incorrect flag after 3 unacknowledged MPDUs");
460 true,
461 "Incorrect flag after 3 unacknowledged MPDUs");
463 true,
464 "Incorrect flag after 3 unacknowledged MPDUs");
466 true,
467 "Incorrect flag after 3 unacknowledged MPDUs");
469 false,
470 "Incorrect flag after 3 unacknowledged MPDUs");
472 false,
473 "Incorrect flag after 3 unacknowledged MPDUs");
475 true,
476 "Incorrect flag after 3 unacknowledged MPDUs");
477 NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(10),
478 true,
479 "Incorrect flag after 3 unacknowledged MPDUs");
480 NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(11),
481 true,
482 "Incorrect flag after 3 unacknowledged MPDUs");
483 for (uint16_t i = 12; i < winSize; i++)
484 {
486 false,
487 "Incorrect flag after 3 unacknowledged MPDUs");
488 }
489
490 // the transmission of an MPDU beyond the current window (by 2 positions) is
491 // notified, hence the window moves forward 2 positions
492 seqNumber = (agreement.m_txWindow.GetWinEnd() + 2) % SEQNO_SPACE_SIZE;
493 mpdu->GetHeader().SetSequenceNumber(seqNumber);
494 agreement.NotifyTransmittedMpdu(mpdu);
495
496 // the current window must look like this:
497 //
498 // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
499 // ^
500 // |
501 // HEAD
502
503 startingSeq = (startingSeq + 2) % SEQNO_SPACE_SIZE;
505 agreement.GetStartingSequence(),
506 startingSeq,
507 "Incorrect starting sequence after transmitting an MPDU beyond the current window");
509 false,
510 "Incorrect flag after transmitting an MPDU beyond the current window");
512 true,
513 "Incorrect flag after transmitting an MPDU beyond the current window");
515 true,
516 "Incorrect flag after transmitting an MPDU beyond the current window");
518 true,
519 "Incorrect flag after transmitting an MPDU beyond the current window");
521 true,
522 "Incorrect flag after transmitting an MPDU beyond the current window");
524 false,
525 "Incorrect flag after transmitting an MPDU beyond the current window");
527 false,
528 "Incorrect flag after transmitting an MPDU beyond the current window");
530 true,
531 "Incorrect flag after transmitting an MPDU beyond the current window");
533 true,
534 "Incorrect flag after transmitting an MPDU beyond the current window");
536 true,
537 "Incorrect flag after transmitting an MPDU beyond the current window");
538 for (uint16_t i = 10; i < winSize; i++)
539 {
541 agreement.m_txWindow.At(i),
542 false,
543 "Incorrect flag after transmitting an MPDU beyond the current window");
544 }
545
546 // another MPDU is transmitted beyond the current window. Now, the window advances
547 // until the first unacknowledged MPDU
548 seqNumber = (agreement.m_txWindow.GetWinEnd() + 1) % SEQNO_SPACE_SIZE;
549 mpdu->GetHeader().SetSequenceNumber(seqNumber);
550 agreement.NotifyTransmittedMpdu(mpdu);
551
552 // the current window must look like this:
553 //
554 // |0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|
555 // ^
556 // |
557 // HEAD
558
559 startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
561 agreement.GetStartingSequence(),
562 startingSeq,
563 "Incorrect starting sequence after transmitting another MPDU beyond the current window");
565 agreement.m_txWindow.At(0),
566 false,
567 "Incorrect flag after transmitting another MPDU beyond the current window");
569 agreement.m_txWindow.At(1),
570 false,
571 "Incorrect flag after transmitting another MPDU beyond the current window");
573 agreement.m_txWindow.At(2),
574 true,
575 "Incorrect flag after transmitting another MPDU beyond the current window");
577 agreement.m_txWindow.At(3),
578 true,
579 "Incorrect flag after transmitting another MPDU beyond the current window");
581 agreement.m_txWindow.At(4),
582 true,
583 "Incorrect flag after transmitting another MPDU beyond the current window");
584 for (uint16_t i = 5; i < winSize; i++)
585 {
587 agreement.m_txWindow.At(i),
588 false,
589 "Incorrect flag after transmitting another MPDU beyond the current window");
590 }
591
592 // the MPDU next to winStart is discarded, hence the window advances to make it an old packet.
593 // Since the subsequent MPDUs have been acknowledged, the window advances further.
594 seqNumber = (startingSeq + 1) % SEQNO_SPACE_SIZE;
595 mpdu->GetHeader().SetSequenceNumber(seqNumber);
596 agreement.NotifyDiscardedMpdu(mpdu);
597
598 // the current window must look like this:
599 //
600 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
601 // ^
602 // |
603 // HEAD
604
605 startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
607 startingSeq,
608 "Incorrect starting sequence after discarding an MPDU");
609 for (uint16_t i = 0; i < winSize; i++)
610 {
612 false,
613 "Incorrect flag after discarding an MPDU");
614 }
615
616 // Finally, check that the window correctly advances when the MPDU with the starting sequence
617 // number is acknowledged after being the only unacknowledged MPDU
618 for (uint16_t i = 1; i < winSize; i++)
619 {
620 mpdu->GetHeader().SetSequenceNumber((startingSeq + i) % SEQNO_SPACE_SIZE);
621 agreement.NotifyAckedMpdu(mpdu);
622 }
623
624 // the current window must look like this:
625 //
626 // |1|1|1|1|1|1|0|1|1|1|1|1|1|1|1|1|
627 // ^
628 // |
629 // HEAD
630
632 startingSeq,
633 "Incorrect starting sequence after acknowledging all but the first MPDU");
635 false,
636 "Incorrect flag after acknowledging all but the first MPDU");
637 for (uint16_t i = 1; i < winSize; i++)
638 {
640 true,
641 "Incorrect flag after acknowledging all but the first MPDU");
642 }
643
644 // acknowledge the first MPDU
645 mpdu->GetHeader().SetSequenceNumber(startingSeq % SEQNO_SPACE_SIZE);
646 agreement.NotifyAckedMpdu(mpdu);
647
648 // the current window must look like this:
649 //
650 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
651 // ^
652 // |
653 // HEAD
654
655 startingSeq = (startingSeq + winSize) % SEQNO_SPACE_SIZE;
657 startingSeq,
658 "Incorrect starting sequence after acknowledging the first MPDU");
659 for (uint16_t i = 0; i < winSize; i++)
660 {
662 false,
663 "Incorrect flag after acknowledging the first MPDU");
664 }
665}
666
667/**
668 * \ingroup wifi-test
669 * \ingroup tests
670 *
671 * \brief Test for block ack header
672 */
674{
675 public:
677
678 private:
679 void DoRun() override;
681};
682
684 : TestCase("Check the correctness of block ack compressed bitmap")
685{
686}
687
688void
690{
692
693 // Case 1: startSeq < endSeq
694 // 179 242
696 for (uint16_t i = 179; i < 220; i++)
697 {
699 }
700 for (uint16_t i = 225; i <= 242; i++)
701 {
703 }
704 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
705 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
706 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0xff, "error in compressed bitmap");
707 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0xff, "error in compressed bitmap");
708 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0xff, "error in compressed bitmap");
709 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0xc1, "error in compressed bitmap");
710 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0xff, "error in compressed bitmap");
711 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0xff, "error in compressed bitmap");
713 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
714 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
715 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0xff, "error in compressed bitmap");
716 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0xff, "error in compressed bitmap");
717 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0xff, "error in compressed bitmap");
718 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0xc1, "error in compressed bitmap");
719 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0xff, "error in compressed bitmap");
720 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0xff, "error in compressed bitmap");
721 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(220), false, "error in compressed bitmap");
722 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(225), true, "error in compressed bitmap");
724 false,
725 "error in compressed bitmap");
726
728
729 // Case 2: startSeq > endSeq
730 // 4090 58
732 for (uint16_t i = 4090; i != 10; i = (i + 1) % 4096)
733 {
735 }
736 for (uint16_t i = 22; i < 25; i++)
737 {
739 }
740 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
741 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
742 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0x00, "error in compressed bitmap");
743 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0x70, "error in compressed bitmap");
744 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0x00, "error in compressed bitmap");
745 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0x00, "error in compressed bitmap");
746 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0x00, "error in compressed bitmap");
747 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0x00, "error in compressed bitmap");
749 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
750 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
751 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0x00, "error in compressed bitmap");
752 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0x70, "error in compressed bitmap");
753 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0x00, "error in compressed bitmap");
754 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0x00, "error in compressed bitmap");
755 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0x00, "error in compressed bitmap");
756 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0x00, "error in compressed bitmap");
757 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(4090), true, "error in compressed bitmap");
758 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(4095), true, "error in compressed bitmap");
759 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(10), false, "error in compressed bitmap");
760 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(35), false, "error in compressed bitmap");
761 NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(80), false, "error in compressed bitmap");
762}
763
764/**
765 * \ingroup wifi-test
766 * \ingroup tests
767 *
768 * \brief Test for recipient reordering buffer operations
769 */
771{
772 public:
773 /**
774 * \brief Constructor
775 * \param ssn the Starting Sequence Number used to initialize WinStartB
776 */
777 BlockAckRecipientBufferTest(uint16_t ssn);
779
780 void DoRun() override;
781
782 /**
783 * Keep track of MPDUs received on the given link that are forwarded up.
784 *
785 * \param mpdu an MPDU that is forwarded up
786 * \param linkId the ID of the given link
787 */
788 void ForwardUp(Ptr<const WifiMpdu> mpdu, uint8_t linkId);
789
790 private:
791 uint16_t m_ssn; //!< the Starting Sequence Number used to initialize WinStartB
792 std::list<Ptr<const WifiMpdu>> m_fwup; //!< list of MPDUs that have been forwarded up
793};
794
796 : TestCase("Test case for Block Ack recipient reordering buffer operations"),
797 m_ssn(ssn)
798{
799}
800
804
805void
807{
808 m_fwup.push_back(mpdu);
809}
810
811void
813{
815 rxMiddle->SetForwardCallback(MakeCallback(&BlockAckRecipientBufferTest::ForwardUp, this));
816
817 RecipientBlockAckAgreement agreement(Mac48Address::Allocate() /* originator */,
818 true /* amsduSupported */,
819 0 /* tid */,
820 10 /* bufferSize */,
821 0 /* timeout */,
822 m_ssn,
823 true /* htSupported */);
824 agreement.SetMacRxMiddle(rxMiddle);
825
826 WifiMacHeader hdr;
829 hdr.SetQosTid(0);
830
831 // Notify the reception of an MPDU with SN = SSN.
834
835 // This MPDU is forwarded up and WinStartB is set to SSN + 1.
836 NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 1, "MPDU with SN=SSN must have been forwarded up");
837 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
838 m_ssn,
839 "The MPDU forwarded up is not the expected one");
840
841 m_fwup.clear();
842
843 // Notify the reception of MPDUs with SN = SSN + {4, 2, 5, 3, 10, 7}
844 // Recipient buffer: | |X|X|X|X| |X| | |X|
845 // ^
846 // |
847 // SSN + 1
860
861 // No MPDU is forwarded up because the one with SN = SSN + 1 is missing
862 NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
863
864 // Notify the reception of an "old" MPDU (SN = SSN)
867
868 // No MPDU is forwarded up
869 NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
870
871 // Notify the reception of a duplicate MPDU (SN = SSN + 2)
874
875 // No MPDU is forwarded up
876 NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
877
878 // Notify the reception of an MPDU with SN = SSN + 1
879 // Recipient buffer: |X|X|X|X|X| |X| | |X|
880 // ^
881 // |
882 // SSN + 1
885
886 // All the MPDUs with SN = SSN + {1, 2, 3, 4, 5} must have been forwarded up in order
887 NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 5, "5 MPDUs must have been forwarded up");
888
889 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
890 (m_ssn + 1) % SEQNO_SPACE_SIZE,
891 "The MPDU forwarded up is not the expected one");
892 m_fwup.pop_front();
893
894 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
895 (m_ssn + 2) % SEQNO_SPACE_SIZE,
896 "The MPDU forwarded up is not the expected one");
897 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetPacketSize(),
898 0,
899 "The MPDU forwarded up is not the expected one");
900 m_fwup.pop_front();
901
902 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
903 (m_ssn + 3) % SEQNO_SPACE_SIZE,
904 "The MPDU forwarded up is not the expected one");
905 m_fwup.pop_front();
906
907 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
908 (m_ssn + 4) % SEQNO_SPACE_SIZE,
909 "The MPDU forwarded up is not the expected one");
910 m_fwup.pop_front();
911
912 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
913 (m_ssn + 5) % SEQNO_SPACE_SIZE,
914 "The MPDU forwarded up is not the expected one");
915 m_fwup.pop_front();
916
917 // Recipient buffer: | |X| | |X| | | | | |
918 // ^ ^
919 // | |
920 // SSN + 6 SSN + 15
921 // Notify the reception of an MPDU beyond the current window (SN = SSN + 17)
924
925 // WinStartB is set to SSN + 8 (so that WinEndB = SSN + 17). The MPDU with
926 // SN = SSN + 7 is forwarded up, irrespective of the missed reception of the
927 // MPDU with SN = SSN + 6
928 NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 1, "One MPDU must have been forwarded up");
929
930 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
931 (m_ssn + 7) % SEQNO_SPACE_SIZE,
932 "The MPDU forwarded up is not the expected one");
933 m_fwup.pop_front();
934
935 // Recipient buffer: | | |X| | | | | | |X|
936 // ^ ^
937 // | |
938 // SSN + 8 SSN + 17
939 // Notify the reception of a BlockAckReq with SSN = SSN + 7
940 agreement.NotifyReceivedBar((m_ssn + 7) % SEQNO_SPACE_SIZE);
941
942 // No MPDU is forwarded up
943 NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
944
945 // Notify the reception of a BlockAckReq with SSN = SSN + 8
946 agreement.NotifyReceivedBar((m_ssn + 8) % SEQNO_SPACE_SIZE);
947
948 // No MPDU is forwarded up
949 NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
950
951 // Notify the reception of MPDUs with SN = SSN + {9, 11}
952 // Recipient buffer: | |X|X|X| | | | | |X|
953 // ^ ^
954 // | |
955 // SSN + 8 SSN + 17
960
961 // No MPDU is forwarded up because the one with SN = SSN + 8 is missing
962 NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
963
964 // Notify the reception of a BlockAckReq with SSN = SSN + 10
965 agreement.NotifyReceivedBar((m_ssn + 10) % SEQNO_SPACE_SIZE);
966
967 // Forward up buffered MPDUs with SN < SSN + 10 (the MPDU with SN = SSN + 9)
968 // and then buffered MPDUs with SN >= SSN + 10 until a hole is found (MPDUs
969 // with SN = SSN + 10 and SN = SSN + 11)
970 NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 3, "3 MPDUs must have been forwarded up");
971
972 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
973 (m_ssn + 9) % SEQNO_SPACE_SIZE,
974 "The MPDU forwarded up is not the expected one");
975 m_fwup.pop_front();
976
977 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
978 (m_ssn + 10) % SEQNO_SPACE_SIZE,
979 "The MPDU forwarded up is not the expected one");
980 m_fwup.pop_front();
981
982 NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
983 (m_ssn + 11) % SEQNO_SPACE_SIZE,
984 "The MPDU forwarded up is not the expected one");
985 m_fwup.pop_front();
986
989}
990
991/**
992 * \ingroup wifi-test
993 * \ingroup tests
994 *
995 * \brief Test for Multi-STA block ack header
996 */
998{
999 public:
1001
1002 private:
1003 void DoRun() override;
1004};
1005
1007 : TestCase("Check the correctness of Multi-STA block ack")
1008{
1009}
1010
1011void
1013{
1014 // Create a Multi-STA Block Ack with 6 Per AID TID Info subfields
1015 BlockAckType baType(BlockAckType::MULTI_STA, {0, 4, 8, 16, 32, 8});
1016
1017 CtrlBAckResponseHeader blockAck;
1018 blockAck.SetType(baType);
1019
1020 /* 1st Per AID TID Info subfield */
1021 uint16_t aid1 = 100;
1022 bool ackType1 = true;
1023 uint8_t tid1 = 1;
1024
1025 blockAck.SetAid11(aid1, 0);
1026 blockAck.SetAckType(ackType1, 0);
1027 blockAck.SetTidInfo(tid1, 0);
1028
1029 /* 2nd Per AID TID Info subfield */
1030 uint16_t aid2 = 200;
1031 bool ackType2 = false;
1032 uint8_t tid2 = 2;
1033 uint16_t startSeq2 = 1000;
1034
1035 blockAck.SetAid11(aid2, 1);
1036 blockAck.SetAckType(ackType2, 1);
1037 blockAck.SetTidInfo(tid2, 1);
1038 blockAck.SetStartingSequence(startSeq2, 1);
1039 // 1st byte of the bitmap: 01010101
1040 for (uint16_t i = startSeq2; i < startSeq2 + 8; i += 2)
1041 {
1042 blockAck.SetReceivedPacket(i, 1);
1043 }
1044 // 2nd byte of the bitmap: 10101010
1045 for (uint16_t i = startSeq2 + 9; i < startSeq2 + 16; i += 2)
1046 {
1047 blockAck.SetReceivedPacket(i, 1);
1048 }
1049 // 3rd byte of the bitmap: 00000000
1050 // 4th byte of the bitmap: 11111111
1051 for (uint16_t i = startSeq2 + 24; i < startSeq2 + 32; i++)
1052 {
1053 blockAck.SetReceivedPacket(i, 1);
1054 }
1055
1056 /* 3rd Per AID TID Info subfield */
1057 uint16_t aid3 = 300;
1058 bool ackType3 = false;
1059 uint8_t tid3 = 3;
1060 uint16_t startSeq3 = 2000;
1061
1062 blockAck.SetAid11(aid3, 2);
1063 blockAck.SetAckType(ackType3, 2);
1064 blockAck.SetTidInfo(tid3, 2);
1065 blockAck.SetStartingSequence(startSeq3, 2);
1066 // 1st byte of the bitmap: 01010101
1067 for (uint16_t i = startSeq3; i < startSeq3 + 8; i += 2)
1068 {
1069 blockAck.SetReceivedPacket(i, 2);
1070 }
1071 // 2nd byte of the bitmap: 10101010
1072 for (uint16_t i = startSeq3 + 9; i < startSeq3 + 16; i += 2)
1073 {
1074 blockAck.SetReceivedPacket(i, 2);
1075 }
1076 // 3rd byte of the bitmap: 00000000
1077 // 4th byte of the bitmap: 11111111
1078 for (uint16_t i = startSeq3 + 24; i < startSeq3 + 32; i++)
1079 {
1080 blockAck.SetReceivedPacket(i, 2);
1081 }
1082 // 5th byte of the bitmap: 00001111
1083 for (uint16_t i = startSeq3 + 32; i < startSeq3 + 36; i++)
1084 {
1085 blockAck.SetReceivedPacket(i, 2);
1086 }
1087 // 6th byte of the bitmap: 11110000
1088 for (uint16_t i = startSeq3 + 44; i < startSeq3 + 48; i++)
1089 {
1090 blockAck.SetReceivedPacket(i, 2);
1091 }
1092 // 7th byte of the bitmap: 00000000
1093 // 8th byte of the bitmap: 11111111
1094 for (uint16_t i = startSeq3 + 56; i < startSeq3 + 64; i++)
1095 {
1096 blockAck.SetReceivedPacket(i, 2);
1097 }
1098
1099 /* 4th Per AID TID Info subfield */
1100 uint16_t aid4 = 400;
1101 bool ackType4 = false;
1102 uint8_t tid4 = 4;
1103 uint16_t startSeq4 = 3000;
1104
1105 blockAck.SetAid11(aid4, 3);
1106 blockAck.SetAckType(ackType4, 3);
1107 blockAck.SetTidInfo(tid4, 3);
1108 blockAck.SetStartingSequence(startSeq4, 3);
1109 // 1st byte of the bitmap: 01010101
1110 for (uint16_t i = startSeq4; i < startSeq4 + 8; i += 2)
1111 {
1112 blockAck.SetReceivedPacket(i, 3);
1113 }
1114 // 2nd byte of the bitmap: 10101010
1115 for (uint16_t i = startSeq4 + 9; i < startSeq4 + 16; i += 2)
1116 {
1117 blockAck.SetReceivedPacket(i, 3);
1118 }
1119 // 3rd byte of the bitmap: 00000000
1120 // 4th byte of the bitmap: 11111111
1121 for (uint16_t i = startSeq4 + 24; i < startSeq4 + 32; i++)
1122 {
1123 blockAck.SetReceivedPacket(i, 3);
1124 }
1125 // 5th byte of the bitmap: 00001111
1126 for (uint16_t i = startSeq4 + 32; i < startSeq4 + 36; i++)
1127 {
1128 blockAck.SetReceivedPacket(i, 3);
1129 }
1130 // 6th byte of the bitmap: 11110000
1131 for (uint16_t i = startSeq4 + 44; i < startSeq4 + 48; i++)
1132 {
1133 blockAck.SetReceivedPacket(i, 3);
1134 }
1135 // 7th byte of the bitmap: 00000000
1136 // 8th byte of the bitmap: 11111111
1137 for (uint16_t i = startSeq4 + 56; i < startSeq4 + 64; i++)
1138 {
1139 blockAck.SetReceivedPacket(i, 3);
1140 }
1141 // 9th byte of the bitmap: 00000000
1142 // 10th byte of the bitmap: 11111111
1143 for (uint16_t i = startSeq4 + 72; i < startSeq4 + 80; i++)
1144 {
1145 blockAck.SetReceivedPacket(i, 3);
1146 }
1147 // 11th byte of the bitmap: 00000000
1148 // 12th byte of the bitmap: 11111111
1149 for (uint16_t i = startSeq4 + 88; i < startSeq4 + 96; i++)
1150 {
1151 blockAck.SetReceivedPacket(i, 3);
1152 }
1153 // 13th byte of the bitmap: 00000000
1154 // 14th byte of the bitmap: 11111111
1155 for (uint16_t i = startSeq4 + 104; i < startSeq4 + 112; i++)
1156 {
1157 blockAck.SetReceivedPacket(i, 3);
1158 }
1159 // 15th byte of the bitmap: 00000000
1160 // 16th byte of the bitmap: 11111111
1161 for (uint16_t i = startSeq4 + 120; i < startSeq4 + 128; i++)
1162 {
1163 blockAck.SetReceivedPacket(i, 3);
1164 }
1165
1166 /* 5th Per AID TID Info subfield */
1167 uint16_t aid5 = 500;
1168 bool ackType5 = false;
1169 uint8_t tid5 = 5;
1170 uint16_t startSeq5 = 4000;
1171
1172 blockAck.SetAid11(aid5, 4);
1173 blockAck.SetAckType(ackType5, 4);
1174 blockAck.SetTidInfo(tid5, 4);
1175 blockAck.SetStartingSequence(startSeq5, 4);
1176 // 1st byte of the bitmap: 01010101
1177 for (int i = startSeq5; i < startSeq5 + 8; i += 2)
1178 {
1179 blockAck.SetReceivedPacket(i, 4);
1180 }
1181 // 2nd byte of the bitmap: 10101010
1182 for (int i = startSeq5 + 9; i < startSeq5 + 16; i += 2)
1183 {
1184 blockAck.SetReceivedPacket(i, 4);
1185 }
1186 // 3rd byte of the bitmap: 00000000
1187 // 4th byte of the bitmap: 11111111
1188 for (int i = startSeq5 + 24; i < startSeq5 + 32; i++)
1189 {
1190 blockAck.SetReceivedPacket(i, 4);
1191 }
1192 // 5th byte of the bitmap: 00001111
1193 for (int i = startSeq5 + 32; i < startSeq5 + 36; i++)
1194 {
1195 blockAck.SetReceivedPacket(i, 4);
1196 }
1197 // 6th byte of the bitmap: 11110000
1198 for (int i = startSeq5 + 44; i < startSeq5 + 48; i++)
1199 {
1200 blockAck.SetReceivedPacket(i, 4);
1201 }
1202 // 7th byte of the bitmap: 00000000
1203 // 8th byte of the bitmap: 11111111
1204 for (int i = startSeq5 + 56; i < startSeq5 + 64; i++)
1205 {
1206 blockAck.SetReceivedPacket(i, 4);
1207 }
1208 // 9th byte of the bitmap: 00000000
1209 // 10th byte of the bitmap: 11111111
1210 for (int i = startSeq5 + 72; i < startSeq5 + 80; i++)
1211 {
1212 blockAck.SetReceivedPacket(i, 4);
1213 }
1214 // 11th byte of the bitmap: 00000000
1215 // 12th byte of the bitmap: 11111111
1216 for (int i = startSeq5 + 88; i < startSeq5 + 96; i++)
1217 {
1218 blockAck.SetReceivedPacket(i, 4);
1219 }
1220 // 13th byte of the bitmap: 00000000
1221 // 14th byte of the bitmap: 11111111
1222 for (int i = (startSeq5 + 104) % 4096; i < (startSeq5 + 112) % 4096; i++)
1223 {
1224 blockAck.SetReceivedPacket(i, 4);
1225 }
1226 // 15th byte of the bitmap: 00000000
1227 // 16th byte of the bitmap: 11111111
1228 for (int i = (startSeq5 + 120) % 4096; i < (startSeq5 + 128) % 4096; i++)
1229 {
1230 blockAck.SetReceivedPacket(i, 4);
1231 }
1232 // 17th byte of the bitmap: 00000000
1233 // 18th byte of the bitmap: 11111111
1234 for (int i = (startSeq5 + 136) % 4096; i < (startSeq5 + 144) % 4096; i++)
1235 {
1236 blockAck.SetReceivedPacket(i, 4);
1237 }
1238 // 19th byte of the bitmap: 00000000
1239 // 20th byte of the bitmap: 11111111
1240 for (int i = (startSeq5 + 152) % 4096; i < (startSeq5 + 160) % 4096; i++)
1241 {
1242 blockAck.SetReceivedPacket(i, 4);
1243 }
1244 // 21th byte of the bitmap: 00000000
1245 // 22th byte of the bitmap: 11111111
1246 for (int i = (startSeq5 + 168) % 4096; i < (startSeq5 + 176) % 4096; i++)
1247 {
1248 blockAck.SetReceivedPacket(i, 4);
1249 }
1250 // 23th byte of the bitmap: 00000000
1251 // 24th byte of the bitmap: 11111111
1252 for (int i = (startSeq5 + 184) % 4096; i < (startSeq5 + 192) % 4096; i++)
1253 {
1254 blockAck.SetReceivedPacket(i, 4);
1255 }
1256 // 25th byte of the bitmap: 00000000
1257 // 26th byte of the bitmap: 11111111
1258 for (int i = (startSeq5 + 200) % 4096; i < (startSeq5 + 208) % 4096; i++)
1259 {
1260 blockAck.SetReceivedPacket(i, 4);
1261 }
1262 // 27th byte of the bitmap: 00000000
1263 // 28th byte of the bitmap: 11111111
1264 for (int i = (startSeq5 + 216) % 4096; i < (startSeq5 + 224) % 4096; i++)
1265 {
1266 blockAck.SetReceivedPacket(i, 4);
1267 }
1268 // 29th byte of the bitmap: 00000000
1269 // 30th byte of the bitmap: 11111111
1270 for (int i = (startSeq5 + 232) % 4096; i < (startSeq5 + 240) % 4096; i++)
1271 {
1272 blockAck.SetReceivedPacket(i, 4);
1273 }
1274 // 31th byte of the bitmap: 00000000
1275 // 32th byte of the bitmap: 11111111
1276 for (int i = (startSeq5 + 248) % 4096; i < (startSeq5 + 256) % 4096; i++)
1277 {
1278 blockAck.SetReceivedPacket(i, 4);
1279 }
1280
1281 /* 6th Per AID TID Info subfield */
1282 uint16_t aid6 = 2045;
1283 bool ackType6 = true;
1284 uint8_t tid6 = 6;
1285 Mac48Address address6("00:00:00:00:00:01");
1286
1287 blockAck.SetAid11(aid6, 5);
1288 blockAck.SetAckType(ackType6, 5);
1289 blockAck.SetTidInfo(tid6, 5);
1290 blockAck.SetUnassociatedStaAddress(address6, 5);
1291
1292 // Serialize the header
1293 Ptr<Packet> packet = Create<Packet>();
1294 packet->AddHeader(blockAck);
1295
1296 // Deserialize the header
1297 CtrlBAckResponseHeader blockAckCopy;
1298 packet->RemoveHeader(blockAckCopy);
1299
1300 // Check that the header has been correctly deserialized
1301 BlockAckType baTypeCopy = blockAckCopy.GetType();
1302
1305 "Different block ack variant");
1306 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen.size(), 6, "Different number of bitmaps");
1307 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[0], 0, "Different length of the first bitmap");
1308 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[1], 4, "Different length of the second bitmap");
1309 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[2], 8, "Different length of the third bitmap");
1310 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[3], 16, "Different length of the fourth bitmap");
1311 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[4], 32, "Different length of the fifth bitmap");
1312 NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[5], 8, "Different length for the sixth bitmap");
1313
1314 /* Check 1st Per AID TID Info subfield */
1315 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(0),
1316 aid1,
1317 "Different AID for the first Per AID TID Info subfield");
1318 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(0),
1319 ackType1,
1320 "Different Ack Type for the first Per AID TID Info subfield");
1321 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(0),
1322 tid1,
1323 "Different TID for the first Per AID TID Info subfield");
1324
1325 /* Check 2nd Per AID TID Info subfield */
1326 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(1),
1327 aid2,
1328 "Different AID for the second Per AID TID Info subfield");
1329 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(1),
1330 ackType2,
1331 "Different Ack Type for the second Per AID TID Info subfield");
1332 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(1),
1333 tid2,
1334 "Different TID for the second Per AID TID Info subfield");
1336 blockAckCopy.GetStartingSequence(1),
1337 startSeq2,
1338 "Different starting sequence number for the second Per AID TID Info subfield");
1339
1340 auto& bitmap2 = blockAckCopy.GetBitmap(1);
1341 NS_TEST_EXPECT_MSG_EQ(bitmap2.size(),
1342 4,
1343 "Different bitmap length for the second Per AID TID Info subfield");
1345 bitmap2[0],
1346 0x55,
1347 "Error in the 1st byte of the bitmap for the second Per AID TID Info subfield");
1349 bitmap2[1],
1350 0xaa,
1351 "Error in the 2nd byte of the bitmap for the second Per AID TID Info subfield");
1353 bitmap2[2],
1354 0x00,
1355 "Error in the 3rd byte of the bitmap for the second Per AID TID Info subfield");
1357 bitmap2[3],
1358 0xff,
1359 "Error in the 4th byte of the bitmap for the second Per AID TID Info subfield");
1360
1361 /* Check 3rd Per AID TID Info subfield */
1362 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(2),
1363 aid3,
1364 "Different AID for the third Per AID TID Info subfield");
1365 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(2),
1366 ackType3,
1367 "Different Ack Type for the third Per AID TID Info subfield");
1368 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(2),
1369 tid3,
1370 "Different TID for the third Per AID TID Info subfield");
1372 blockAckCopy.GetStartingSequence(2),
1373 startSeq3,
1374 "Different starting sequence number for the third Per AID TID Info subfield");
1375
1376 auto& bitmap3 = blockAckCopy.GetBitmap(2);
1377 NS_TEST_EXPECT_MSG_EQ(bitmap3.size(),
1378 8,
1379 "Different bitmap length for the third Per AID TID Info subfield");
1381 bitmap3[0],
1382 0x55,
1383 "Error in the 1st byte of the bitmap for the third Per AID TID Info subfield");
1385 bitmap3[1],
1386 0xaa,
1387 "Error in the 2nd byte of the bitmap for the third Per AID TID Info subfield");
1389 bitmap3[2],
1390 0x00,
1391 "Error in the 3rd byte of the bitmap for the third Per AID TID Info subfield");
1393 bitmap3[3],
1394 0xff,
1395 "Error in the 4th byte of the bitmap for the third Per AID TID Info subfield");
1397 bitmap3[4],
1398 0x0f,
1399 "Error in the 5th byte of the bitmap for the third Per AID TID Info subfield");
1401 bitmap3[5],
1402 0xf0,
1403 "Error in the 6th byte of the bitmap for the third Per AID TID Info subfield");
1405 bitmap3[6],
1406 0x00,
1407 "Error in the 7th byte of the bitmap for the third Per AID TID Info subfield");
1409 bitmap3[7],
1410 0xff,
1411 "Error in the 8th byte of the bitmap for the third Per AID TID Info subfield");
1412
1413 /* Check 4th Per AID TID Info subfield */
1414 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(3),
1415 aid4,
1416 "Different AID for the fourth Per AID TID Info subfield");
1417 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(3),
1418 ackType4,
1419 "Different Ack Type for the fourth Per AID TID Info subfield");
1420 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(3),
1421 tid4,
1422 "Different TID for the fourth Per AID TID Info subfield");
1424 blockAckCopy.GetStartingSequence(3),
1425 startSeq4,
1426 "Different starting sequence number for the fourth Per AID TID Info subfield");
1427
1428 auto& bitmap4 = blockAckCopy.GetBitmap(3);
1429 NS_TEST_EXPECT_MSG_EQ(bitmap4.size(),
1430 16,
1431 "Different bitmap length for the fourth Per AID TID Info subfield");
1433 bitmap4[0],
1434 0x55,
1435 "Error in the 1st byte of the bitmap for the fourth Per AID TID Info subfield");
1437 bitmap4[1],
1438 0xaa,
1439 "Error in the 2nd byte of the bitmap for the fourth Per AID TID Info subfield");
1441 bitmap4[2],
1442 0x00,
1443 "Error in the 3rd byte of the bitmap for the fourth Per AID TID Info subfield");
1445 bitmap4[3],
1446 0xff,
1447 "Error in the 4th byte of the bitmap for the fourth Per AID TID Info subfield");
1449 bitmap4[4],
1450 0x0f,
1451 "Error in the 5th byte of the bitmap for the fourth Per AID TID Info subfield");
1453 bitmap4[5],
1454 0xf0,
1455 "Error in the 6th byte of the bitmap for the fourth Per AID TID Info subfield");
1457 bitmap4[6],
1458 0x00,
1459 "Error in the 7th byte of the bitmap for the fourth Per AID TID Info subfield");
1461 bitmap4[7],
1462 0xff,
1463 "Error in the 8th byte of the bitmap for the fourth Per AID TID Info subfield");
1465 bitmap4[8],
1466 0x00,
1467 "Error in the 9th byte of the bitmap for the fourth Per AID TID Info subfield");
1469 bitmap4[9],
1470 0xff,
1471 "Error in the 10th byte of the bitmap for the fourth Per AID TID Info subfield");
1473 bitmap4[10],
1474 0x00,
1475 "Error in the 11th byte of the bitmap for the fourth Per AID TID Info subfield");
1477 bitmap4[11],
1478 0xff,
1479 "Error in the 12th byte of the bitmap for the fourth Per AID TID Info subfield");
1481 bitmap4[12],
1482 0x00,
1483 "Error in the 13th byte of the bitmap for the fourth Per AID TID Info subfield");
1485 bitmap4[13],
1486 0xff,
1487 "Error in the 14th byte of the bitmap for the fourth Per AID TID Info subfield");
1489 bitmap4[14],
1490 0x00,
1491 "Error in the 15th byte of the bitmap for the fourth Per AID TID Info subfield");
1493 bitmap4[15],
1494 0xff,
1495 "Error in the 16th byte of the bitmap for the fourth Per AID TID Info subfield");
1496
1497 /* Check 5th Per AID TID Info subfield */
1498 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(4),
1499 aid5,
1500 "Different AID for the fifth Per AID TID Info subfield");
1501 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(4),
1502 ackType5,
1503 "Different Ack Type for the fifth Per AID TID Info subfield");
1504 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(4),
1505 tid5,
1506 "Different TID for the fifth Per AID TID Info subfield");
1508 blockAckCopy.GetStartingSequence(4),
1509 startSeq5,
1510 "Different starting sequence number for the fifth Per AID TID Info subfield");
1511
1512 auto& bitmap5 = blockAckCopy.GetBitmap(4);
1513 NS_TEST_EXPECT_MSG_EQ(bitmap5.size(),
1514 32,
1515 "Different bitmap length for the fifth Per AID TID Info subfield");
1517 bitmap5[0],
1518 0x55,
1519 "Error in the 1st byte of the bitmap for the fifth Per AID TID Info subfield");
1521 bitmap5[1],
1522 0xaa,
1523 "Error in the 2nd byte of the bitmap for the fifth Per AID TID Info subfield");
1525 bitmap5[2],
1526 0x00,
1527 "Error in the 3rd byte of the bitmap for the fifth Per AID TID Info subfield");
1529 bitmap5[3],
1530 0xff,
1531 "Error in the 4th byte of the bitmap for the fifth Per AID TID Info subfield");
1533 bitmap5[4],
1534 0x0f,
1535 "Error in the 5th byte of the bitmap for the fifth Per AID TID Info subfield");
1537 bitmap5[5],
1538 0xf0,
1539 "Error in the 6th byte of the bitmap for the fifth Per AID TID Info subfield");
1541 bitmap5[6],
1542 0x00,
1543 "Error in the 7th byte of the bitmap for the fifth Per AID TID Info subfield");
1545 bitmap5[7],
1546 0xff,
1547 "Error in the 8th byte of the bitmap for the fifth Per AID TID Info subfield");
1549 bitmap5[8],
1550 0x00,
1551 "Error in the 9th byte of the bitmap for the fifth Per AID TID Info subfield");
1553 bitmap5[9],
1554 0xff,
1555 "Error in the 10th byte of the bitmap for the fifth Per AID TID Info subfield");
1557 bitmap5[10],
1558 0x00,
1559 "Error in the 11th byte of the bitmap for the fifth Per AID TID Info subfield");
1561 bitmap5[11],
1562 0xff,
1563 "Error in the 12th byte of the bitmap for the fifth Per AID TID Info subfield");
1565 bitmap5[12],
1566 0x00,
1567 "Error in the 13th byte of the bitmap for the fifth Per AID TID Info subfield");
1569 bitmap5[13],
1570 0xff,
1571 "Error in the 14th byte of the bitmap for the fifth Per AID TID Info subfield");
1573 bitmap5[14],
1574 0x00,
1575 "Error in the 15th byte of the bitmap for the fifth Per AID TID Info subfield");
1577 bitmap5[15],
1578 0xff,
1579 "Error in the 16th byte of the bitmap for the fifth Per AID TID Info subfield");
1581 bitmap5[16],
1582 0x00,
1583 "Error in the 17th byte of the bitmap for the fifth Per AID TID Info subfield");
1585 bitmap5[17],
1586 0xff,
1587 "Error in the 18th byte of the bitmap for the fifth Per AID TID Info subfield");
1589 bitmap5[18],
1590 0x00,
1591 "Error in the 19th byte of the bitmap for the fifth Per AID TID Info subfield");
1593 bitmap5[19],
1594 0xff,
1595 "Error in the 20th byte of the bitmap for the fifth Per AID TID Info subfield");
1597 bitmap5[20],
1598 0x00,
1599 "Error in the 21th byte of the bitmap for the fifth Per AID TID Info subfield");
1601 bitmap5[21],
1602 0xff,
1603 "Error in the 22th byte of the bitmap for the fifth Per AID TID Info subfield");
1605 bitmap5[22],
1606 0x00,
1607 "Error in the 23th byte of the bitmap for the fifth Per AID TID Info subfield");
1609 bitmap5[23],
1610 0xff,
1611 "Error in the 24th byte of the bitmap for the fifth Per AID TID Info subfield");
1613 bitmap5[24],
1614 0x00,
1615 "Error in the 25th byte of the bitmap for the fifth Per AID TID Info subfield");
1617 bitmap5[25],
1618 0xff,
1619 "Error in the 26th byte of the bitmap for the fifth Per AID TID Info subfield");
1621 bitmap5[26],
1622 0x00,
1623 "Error in the 27th byte of the bitmap for the fifth Per AID TID Info subfield");
1625 bitmap5[27],
1626 0xff,
1627 "Error in the 28th byte of the bitmap for the fifth Per AID TID Info subfield");
1629 bitmap5[28],
1630 0x00,
1631 "Error in the 29th byte of the bitmap for the fifth Per AID TID Info subfield");
1633 bitmap5[29],
1634 0xff,
1635 "Error in the 30th byte of the bitmap for the fifth Per AID TID Info subfield");
1637 bitmap5[30],
1638 0x00,
1639 "Error in the 31th byte of the bitmap for the fifth Per AID TID Info subfield");
1641 bitmap5[31],
1642 0xff,
1643 "Error in the 32th byte of the bitmap for the fifth Per AID TID Info subfield");
1644
1645 /* Check 6th Per AID TID Info subfield */
1646 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(5),
1647 aid6,
1648 "Different AID for the sixth Per AID TID Info subfield");
1649 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(5),
1650 ackType6,
1651 "Different Ack Type for the sixth Per AID TID Info subfield");
1652 NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(5),
1653 tid6,
1654 "Different TID for the sixth Per AID TID Info subfield");
1656 blockAckCopy.GetUnassociatedStaAddress(5),
1657 address6,
1658 "Different starting sequence number for the sixth Per AID TID Info subfield");
1659}
1660
1661/**
1662 * \ingroup wifi-test
1663 * \ingroup tests
1664 *
1665 * \brief Test for Block Ack Policy with aggregation disabled
1666 *
1667 * This test aims to check the Block Ack policy when A-MPDU aggregation is disabled.
1668 * In this case, a QoS station can transmit multiple QoS data frames before requesting
1669 * a Block Ack through a Block Ack Request frame. If the AC is granted a non-null TXOP
1670 * limit, MPDUs can be separated by a SIFS.
1671 *
1672 * In this test, an HT STA sends 14 packets to an HT AP. The ack policy selector is
1673 * configured so that a Block Ack is requested once 8 (= 0.125 * 64) MPDUs are sent
1674 * in addition to the MPDU having the starting sequence number. The block ack threshold
1675 * is set to 2, hence a block ack agreement is established when there are at least two
1676 * packets in the EDCA queue.
1677 *
1678 * When the TXOP limit is null:
1679 * - the first packet is sent with Normal Ack policy because the BA agreement has not
1680 * been established yet (there are no queued packets when the first one arrives);
1681 * - packets from the 2nd to the 10th are sent with Block Ack policy (and hence
1682 * are not immediately acknowledged);
1683 * - after the 10th packet, a Block Ack Request is sent, followed by a Block Ack;
1684 * - the remaining 4 packets are sent with Block Ack policy (and hence
1685 * are not immediately acknowledged);
1686 * - the last packet is followed by a Block Ack Request because there are no more
1687 * packets in the EDCA queue and hence a response is needed independently of
1688 * the number of outstanding MPDUs.
1689 *
1690 * When the TXOP is not null (and long enough to include the transmission of all packets):
1691 * - the first packet is sent with Normal Ack policy because the BA agreement has not
1692 * been established yet (there are no queued packets when the first one arrives);
1693 * - the second packet is sent with Normal Ack Policy because the first packet sent in
1694 * a TXOP shall request an immediate response and no previous MPDUs have to be
1695 * acknowledged;
1696 * - packets from the 3rd to the 11th are sent with Block Ack policy (and hence
1697 * are not immediately acknowledged);
1698 * - after the 11th packet, a Block Ack Request is sent, followed by a Block Ack;
1699 * - the remaining 3 packets are sent with Block Ack policy (and hence
1700 * are not immediately acknowledged);
1701 * - the last packet is followed by a Block Ack Request because there are no more
1702 * packets in the EDCA queue and hence a response is needed independently of
1703 * the number of outstanding MPDUs.
1704 */
1706{
1707 /**
1708 * Keeps the maximum duration among all TXOPs
1709 */
1711 {
1712 /**
1713 * Callback for the TxopTrace trace
1714 * \param startTime TXOP start time
1715 * \param duration TXOP duration
1716 * \param linkId the ID of the link
1717 */
1718 void Trace(Time startTime, Time duration, uint8_t linkId);
1719 Time m_max{Seconds(0)}; ///< max TXOP duration
1720 };
1721
1722 public:
1723 /**
1724 * \brief Constructor
1725 * \param txop true for non-null TXOP limit
1726 */
1729
1730 void DoRun() override;
1731
1732 private:
1733 bool m_txop; ///< true for non-null TXOP limit
1734 uint32_t m_received; ///< received packets
1735 uint16_t m_txTotal; ///< transmitted data packets
1736 uint16_t m_txSinceBar; ///< packets transmitted since the agreement was established
1737 ///< or the last block ack was received
1738 uint16_t m_nBar; ///< transmitted BlockAckReq frames
1739 uint16_t m_nBa; ///< received BlockAck frames
1740
1741 /**
1742 * Function to trace packets received by the server application
1743 * \param context the context
1744 * \param p the packet
1745 * \param adr the address
1746 */
1747 void L7Receive(std::string context, Ptr<const Packet> p, const Address& adr);
1748 /**
1749 * Callback invoked when PHY transmits a packet
1750 * \param context the context
1751 * \param p the packet
1752 * \param power the tx power
1753 */
1754 void Transmit(std::string context, Ptr<const Packet> p, double power);
1755 /**
1756 * Callback invoked when PHY receives a packet
1757 * \param context the context
1758 * \param p the packet
1759 * \param rxPowersW the received power per channel band in watts
1760 */
1761 void Receive(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1762};
1763
1764void
1766 Time duration,
1767 uint8_t linkId)
1768{
1769 if (duration > m_max)
1770 {
1771 m_max = duration;
1772 }
1773}
1774
1776 : TestCase("Test case for Block Ack Policy with aggregation disabled"),
1777 m_txop(txop),
1778 m_received(0),
1779 m_txTotal(0),
1780 m_txSinceBar(0),
1781 m_nBar(0),
1782 m_nBa(0)
1783{
1784}
1785
1789
1790void
1793 const Address& adr)
1794{
1795 if (p->GetSize() == 1400)
1796 {
1797 m_received++;
1798 }
1799}
1800
1801void
1803{
1804 WifiMacHeader hdr;
1805 p->PeekHeader(hdr);
1806
1807 if (m_nBar < 2 && (m_txSinceBar == 9 || m_txTotal == 14))
1808 {
1809 NS_TEST_ASSERT_MSG_EQ(hdr.IsBlockAckReq(), true, "Didn't get a BlockAckReq when expected");
1810 }
1811 else
1812 {
1813 NS_TEST_ASSERT_MSG_EQ(hdr.IsBlockAckReq(), false, "Got a BlockAckReq when not expected");
1814 }
1815
1816 if (hdr.IsQosData())
1817 {
1818 m_txTotal++;
1819 if (hdr.IsQosBlockAck())
1820 {
1821 m_txSinceBar++;
1822 }
1823
1824 if (!m_txop)
1825 {
1827 true,
1828 "Unexpected QoS ack policy");
1829 }
1830 else
1831 {
1833 true,
1834 "Unexpected QoS ack policy");
1835 }
1836 }
1837 else if (hdr.IsBlockAckReq())
1838 {
1839 m_txSinceBar = 0;
1840 m_nBar++;
1841 }
1842}
1843
1844void
1847 RxPowerWattPerChannelBand rxPowersW)
1848{
1849 WifiMacHeader hdr;
1850 p->PeekHeader(hdr);
1851
1852 if (hdr.IsBlockAck())
1853 {
1854 m_nBa++;
1855 }
1856}
1857
1858void
1860{
1861 NodeContainer wifiStaNode;
1862 wifiStaNode.Create(1);
1863
1864 NodeContainer wifiApNode;
1865 wifiApNode.Create(1);
1866
1869 phy.SetChannel(channel.Create());
1870
1871 WifiHelper wifi;
1872 wifi.SetStandard(WIFI_STANDARD_80211n);
1873 Config::SetDefault("ns3::WifiDefaultAckManager::BaThreshold", DoubleValue(0.125));
1874 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1875
1876 WifiMacHelper mac;
1877 Ssid ssid = Ssid("ns-3-ssid");
1878 mac.SetType("ns3::StaWifiMac",
1879 "BE_MaxAmsduSize",
1880 UintegerValue(0),
1881 "BE_MaxAmpduSize",
1882 UintegerValue(0),
1883 "Ssid",
1884 SsidValue(ssid),
1885 /* setting blockack threshold for sta's BE queue */
1886 "BE_BlockAckThreshold",
1887 UintegerValue(2),
1888 "ActiveProbing",
1889 BooleanValue(false));
1890
1891 NetDeviceContainer staDevices;
1892 staDevices = wifi.Install(phy, mac, wifiStaNode);
1893
1894 mac.SetType("ns3::ApWifiMac",
1895 "BE_MaxAmsduSize",
1896 UintegerValue(0),
1897 "BE_MaxAmpduSize",
1898 UintegerValue(0),
1899 "Ssid",
1900 SsidValue(ssid),
1901 "BeaconGeneration",
1902 BooleanValue(true));
1903
1904 if (m_txop)
1905 {
1906 // set the TXOP limit on BE AC
1907 mac.SetEdca(AC_BE,
1908 "TxopLimits",
1910 }
1911
1912 NetDeviceContainer apDevices;
1913 apDevices = wifi.Install(phy, mac, wifiApNode);
1914
1915 MobilityHelper mobility;
1917
1918 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1919 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
1920 mobility.SetPositionAllocator(positionAlloc);
1921
1922 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1923 mobility.Install(wifiApNode);
1924 mobility.Install(wifiStaNode);
1925
1926 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
1927 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
1928
1929 // Disable A-MPDU aggregation
1930 sta_device->GetMac()->SetAttribute("BE_MaxAmpduSize", UintegerValue(0));
1931 TxopDurationTracer txopTracer;
1932
1933 if (m_txop)
1934 {
1935 PointerValue ptr;
1936 sta_device->GetMac()->GetAttribute("BE_Txop", ptr);
1937 ptr.Get<QosTxop>()->TraceConnectWithoutContext(
1938 "TxopTrace",
1940 }
1941
1942 PacketSocketAddress socket;
1943 socket.SetSingleDevice(sta_device->GetIfIndex());
1944 socket.SetPhysicalAddress(ap_device->GetAddress());
1945 socket.SetProtocol(1);
1946
1947 // give packet socket powers to nodes.
1948 PacketSocketHelper packetSocket;
1949 packetSocket.Install(wifiStaNode);
1950 packetSocket.Install(wifiApNode);
1951
1952 // the first client application generates a single packet, which is sent
1953 // with the normal ack policy because there are no other packets queued
1955 client1->SetAttribute("PacketSize", UintegerValue(1400));
1956 client1->SetAttribute("MaxPackets", UintegerValue(1));
1957 client1->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
1958 client1->SetRemote(socket);
1959 wifiStaNode.Get(0)->AddApplication(client1);
1960 client1->SetStartTime(Seconds(1));
1961 client1->SetStopTime(Seconds(3.0));
1962
1963 // the second client application generates 13 packets. Even if when the first
1964 // packet is queued the queue is empty, the first packet is not transmitted
1965 // immediately, but the EDCAF waits for the next slot boundary. At that time,
1966 // other packets have been queued, hence a BA agreement is established first.
1968 client2->SetAttribute("PacketSize", UintegerValue(1400));
1969 client2->SetAttribute("MaxPackets", UintegerValue(13));
1970 client2->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
1971 client2->SetRemote(socket);
1972 wifiStaNode.Get(0)->AddApplication(client2);
1973 client2->SetStartTime(Seconds(1.5));
1974 client2->SetStopTime(Seconds(3.0));
1975
1977 server->SetLocal(socket);
1978 wifiApNode.Get(0)->AddApplication(server);
1979 server->SetStartTime(Seconds(0.0));
1980 server->SetStopTime(Seconds(4.0));
1981
1982 Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
1984 Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyTxBegin",
1986 Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyRxBegin",
1988
1991
1993
1994 // The client applications generate 14 packets, so we expect that the wifi PHY
1995 // layer transmits 14 MPDUs, the server application receives 14 packets, and
1996 // two BARs are transmitted.
1997 NS_TEST_EXPECT_MSG_EQ(m_txTotal, 14, "Unexpected number of transmitted packets");
1998 NS_TEST_EXPECT_MSG_EQ(m_received, 14, "Unexpected number of received packets");
1999 NS_TEST_EXPECT_MSG_EQ(m_nBar, 2, "Unexpected number of Block Ack Requests");
2000 NS_TEST_EXPECT_MSG_EQ(m_nBa, 2, "Unexpected number of Block Ack Responses");
2001 if (m_txop)
2002 {
2003 NS_TEST_EXPECT_MSG_LT(txopTracer.m_max, MicroSeconds(4800), "TXOP duration exceeded!");
2004 NS_TEST_EXPECT_MSG_GT(txopTracer.m_max,
2005 MicroSeconds(3008),
2006 "The maximum TXOP duration is too short!");
2007 }
2008}
2009
2010/**
2011 * \ingroup wifi-test
2012 * \ingroup tests
2013 *
2014 * \brief Test for Block Ack Policy with non-null BA threshold and TX window blocked.
2015 *
2016 * An EHT device establishes a Block Ack agreement (for TID 0) with the AP and uses a Block Ack
2017 * threshold of 0.125 (i.e., Block Ack is requested if there are at least 64 * 0.125 = 8 MPDUs
2018 * to be acknowledged, where 64 is the Block Ack buffer size). An application installed on the
2019 * non-AP node generates 70 packets, hence an A-MPDU containing the first 64 MPDUs is transmitted.
2020 * The first 5 MPDUs in that A-MPDU are corrupted. We check that:
2021 *
2022 * - the first A-MPDU contains MPDUs with sequence numbers from 0 to 63
2023 * - the second A-MPDU contains the 5 retransmitted MPDUs (with sequence numbers from 0 to 4) only,
2024 * because the TX window is blocked
2025 * - the third A-MPDU contains the remaining 6 MPDUs (with sequence numbers from 64 to 69)
2026 * - 3 A-MPDUs and 3 BlockAck frames are transmitted during the simulation
2027 * - the MAC queue is empty at the end of simulation (meaning that all MPDUs were acknowledged)
2028 */
2030{
2031 public:
2032 /**
2033 * \param mld whether the non-AP device is a multi-link device
2034 */
2035 OrigBlockAckWindowStalled(bool mld);
2036
2037 /**
2038 * Callback invoked when a FEM passes PSDUs to the PHY.
2039 *
2040 * \param psduMap the PSDU map
2041 * \param txVector the TX vector
2042 * \param txPowerW the tx power in Watts
2043 */
2044 void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
2045
2046 private:
2047 void DoSetup() override;
2048 void DoRun() override;
2049
2050 const uint8_t m_nLinks; ///< number of links
2051 const double m_baThreshold{0.125}; ///< BA threshold used by ack manager
2052 const std::size_t m_nPkts{70}; ///< number of generated packets
2053 Ptr<ListErrorModel> m_errorModel; ///< error rate model to corrupt packets
2054 Ptr<WifiNetDevice> m_staDevice; ///< station WifiNetDevice
2055 std::size_t m_qosCount{0}; ///< counter for transmitted QoS data frames
2056 std::size_t m_baCount{0}; ///< counter for transmitted BlockAck frames
2057};
2058
2060 : TestCase("Test case for originator Block Ack window stalled"),
2061 m_nLinks(mld ? 2 : 1)
2062{
2063}
2064
2065void
2067 WifiTxVector txVector,
2068 double txPowerW)
2069{
2070 for (const auto& [aid, psdu] : psduMap)
2071 {
2072 std::stringstream ss;
2073 ss << " #MPDUs " << psdu->GetNMpdus();
2074 for (const auto& mpdu : *PeekPointer(psdu))
2075 {
2076 ss << "\n" << *mpdu;
2077 }
2078
2079 if (const auto& hdr = (*psdu->begin())->GetHeader(); hdr.IsQosData())
2080 {
2081 // check sequence numbers in the transmitted A-MPDU
2082 uint16_t startSeqN{0};
2083 std::size_t count{0};
2084
2085 switch (++m_qosCount)
2086 {
2087 case 1:
2088 startSeqN = 0;
2089 count = 64;
2090 break;
2091 case 2:
2092 startSeqN = 0;
2093 count = 5;
2094 break;
2095 case 3:
2096 startSeqN = 64;
2097 count = 6;
2098 break;
2099 default:;
2100 }
2101
2102 NS_TEST_EXPECT_MSG_EQ(psdu->GetNMpdus(),
2103 count,
2104 "Unexpected number of MPDUs in A-MPDU #" << m_qosCount);
2105
2106 for (const auto& mpdu : *PeekPointer(psdu))
2107 {
2108 NS_TEST_EXPECT_MSG_GT_OR_EQ(mpdu->GetHeader().GetSequenceNumber(),
2109 startSeqN,
2110 "Unexpected SeqN in A-MPDU #" << m_qosCount);
2111 NS_TEST_EXPECT_MSG_LT(mpdu->GetHeader().GetSequenceNumber(),
2112 startSeqN + count,
2113 "Unexpected SeqN in A-MPDU #" << m_qosCount);
2114 }
2115
2116 // reset UIDs to corrupt
2117 m_errorModel->SetList({});
2118
2119 // corrupt the first 5 MPDUs of the second QoS data frame
2120 if (m_qosCount == 1)
2121 {
2122 auto mpduIt = psdu->begin();
2123 std::list<uint64_t> uids;
2124 ss << "\nCORRUPTED";
2125 for (std::size_t i = 0; i < 5; ++i, ++mpduIt)
2126 {
2127 uids.push_back((*mpduIt)->GetPacket()->GetUid());
2128 ss << " " << (*mpduIt)->GetHeader().GetSequenceNumber();
2129 }
2130 m_errorModel->SetList(uids);
2131 }
2132 }
2133 else if (hdr.IsBlockAck())
2134 {
2135 ++m_baCount;
2136 }
2137
2138 NS_LOG_INFO(ss.str());
2139 }
2140 NS_LOG_INFO("TXVECTOR = " << txVector << "\n");
2141}
2142
2143void
2145{
2146 NodeContainer wifiStaNode(1);
2147 NodeContainer wifiApNode(1);
2148
2151 phy.Set(0, "ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
2152 if (m_nLinks > 1)
2153 {
2154 phy.Set(1, "ChannelSettings", StringValue("{100, 0, BAND_5GHZ, 0}"));
2155 }
2156 phy.SetChannel(channel);
2157
2158 WifiHelper wifi;
2159 wifi.SetStandard(WIFI_STANDARD_80211be);
2160 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2161 "DataMode",
2162 StringValue("EhtMcs7"),
2163 "ControlMode",
2164 StringValue("EhtMcs0"));
2165
2166 WifiMacHelper mac;
2167 mac.SetAckManager("ns3::WifiDefaultAckManager", "BaThreshold", DoubleValue(m_baThreshold));
2168 mac.SetType("ns3::StaWifiMac", "MpduBufferSize", UintegerValue(64));
2169
2170 auto staDevices = wifi.Install(phy, mac, wifiStaNode);
2171
2172 mac.SetType("ns3::ApWifiMac");
2173
2174 auto apDevices = wifi.Install(phy, mac, wifiApNode);
2175
2177 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2178 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2179
2180 MobilityHelper mobility;
2181 mobility.SetPositionAllocator(positionAlloc);
2182 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2183 mobility.Install(wifiApNode);
2184 mobility.Install(wifiStaNode);
2185
2186 auto apDevice = DynamicCast<WifiNetDevice>(apDevices.Get(0));
2187 m_staDevice = DynamicCast<WifiNetDevice>(staDevices.Get(0));
2188
2190 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phys/*/PhyTxPsduBegin",
2192
2193 // install post reception error model on AP
2195 apDevice->GetPhy(0)->SetPostReceptionErrorModel(m_errorModel);
2196 if (m_nLinks > 1)
2197 {
2198 apDevice->GetPhy(1)->SetPostReceptionErrorModel(m_errorModel);
2199 }
2200
2201 PacketSocketAddress socket;
2202 socket.SetSingleDevice(m_staDevice->GetIfIndex());
2203 socket.SetPhysicalAddress(apDevice->GetAddress());
2204 socket.SetProtocol(1);
2205
2206 // give packet socket powers to nodes.
2207 PacketSocketHelper packetSocket;
2208 packetSocket.Install(wifiStaNode);
2209 packetSocket.Install(wifiApNode);
2210
2211 auto client = CreateObject<PacketSocketClient>();
2212 client->SetAttribute("PacketSize", UintegerValue(100));
2213 client->SetAttribute("MaxPackets", UintegerValue(m_nPkts));
2214 client->SetAttribute("Interval", TimeValue(Time{0}));
2215 client->SetRemote(socket);
2216 wifiStaNode.Get(0)->AddApplication(client);
2217 client->SetStartTime(Seconds(0.5));
2218 client->SetStopTime(Seconds(3.0));
2219
2220 auto server = CreateObject<PacketSocketServer>();
2221 server->SetLocal(socket);
2222 wifiApNode.Get(0)->AddApplication(server);
2223 server->SetStartTime(Seconds(0.0));
2224 server->SetStopTime(Seconds(4.0));
2225}
2226
2227void
2229{
2232
2233 NS_TEST_EXPECT_MSG_EQ(m_qosCount, 3, "Unexpected number of transmitted QoS data frames");
2234 NS_TEST_EXPECT_MSG_EQ(m_baCount, 3, "Unexpected number of transmitted BlockAck frames");
2235
2236 NS_TEST_EXPECT_MSG_EQ(m_staDevice->GetMac()->GetTxopQueue(AC_BE)->IsEmpty(),
2237 true,
2238 "Expected no packet in STA queue");
2239
2241}
2242
2243/**
2244 * \ingroup wifi-test
2245 * \ingroup tests
2246 *
2247 * \brief Block Ack Test Suite
2248 */
2250{
2251 public:
2253};
2254
2256 : TestSuite("wifi-block-ack", Type::UNIT)
2257{
2258 AddTestCase(new PacketBufferingCaseA, TestCase::Duration::QUICK);
2259 AddTestCase(new PacketBufferingCaseB, TestCase::Duration::QUICK);
2260 AddTestCase(new OriginatorBlockAckWindowTest, TestCase::Duration::QUICK);
2261 AddTestCase(new CtrlBAckResponseHeaderTest, TestCase::Duration::QUICK);
2262 AddTestCase(new BlockAckRecipientBufferTest(0), TestCase::Duration::QUICK);
2263 AddTestCase(new BlockAckRecipientBufferTest(4090), TestCase::Duration::QUICK);
2264 AddTestCase(new MultiStaCtrlBAckResponseHeaderTest, TestCase::Duration::QUICK);
2265 AddTestCase(new BlockAckAggregationDisabledTest(false), TestCase::Duration::QUICK);
2266 AddTestCase(new BlockAckAggregationDisabledTest(true), TestCase::Duration::QUICK);
2267 AddTestCase(new OrigBlockAckWindowStalled(false), TestCase::Duration::QUICK);
2268 AddTestCase(new OrigBlockAckWindowStalled(true), TestCase::Duration::QUICK);
2269}
2270
2271static BlockAckTestSuite g_blockAckTestSuite; ///< the test suite
static BlockAckTestSuite g_blockAckTestSuite
the test suite
Test for Block Ack Policy with aggregation disabled.
uint16_t m_nBa
received BlockAck frames
uint16_t m_txTotal
transmitted data packets
void L7Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Function to trace packets received by the server application.
BlockAckAggregationDisabledTest(bool txop)
Constructor.
uint16_t m_nBar
transmitted BlockAckReq frames
void Receive(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback invoked when PHY receives a packet.
void Transmit(std::string context, Ptr< const Packet > p, double power)
Callback invoked when PHY transmits a packet.
uint16_t m_txSinceBar
packets transmitted since the agreement was established or the last block ack was received
void DoRun() override
Implementation to actually run this TestCase.
bool m_txop
true for non-null TXOP limit
Test for recipient reordering buffer operations.
void DoRun() override
Implementation to actually run this TestCase.
uint16_t m_ssn
the Starting Sequence Number used to initialize WinStartB
BlockAckRecipientBufferTest(uint16_t ssn)
Constructor.
std::list< Ptr< const WifiMpdu > > m_fwup
list of MPDUs that have been forwarded up
void ForwardUp(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Keep track of MPDUs received on the given link that are forwarded up.
Block Ack Test Suite.
Test for block ack header.
CtrlBAckResponseHeader m_blockAckHdr
block ack header
void DoRun() override
Implementation to actually run this TestCase.
Test for Multi-STA block ack header.
void DoRun() override
Implementation to actually run this TestCase.
Test for Block Ack Policy with non-null BA threshold and TX window blocked.
std::size_t m_baCount
counter for transmitted BlockAck frames
const std::size_t m_nPkts
number of generated packets
const uint8_t m_nLinks
number of links
Ptr< WifiNetDevice > m_staDevice
station WifiNetDevice
std::size_t m_qosCount
counter for transmitted QoS data frames
Ptr< ListErrorModel > m_errorModel
error rate model to corrupt packets
void DoRun() override
Implementation to actually run this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
const double m_baThreshold
BA threshold used by ack manager.
void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when a FEM passes PSDUs to the PHY.
Test for the originator block ack window.
void DoRun() override
Implementation to actually run this TestCase.
Packet Buffering Case A.
std::list< uint16_t > m_expectedBuffer
expected test buffer
void DoRun() override
Implementation to actually run this TestCase.
Packet Buffering Case B.
std::list< uint16_t > m_expectedBuffer
expected test buffer
void DoRun() override
Implementation to actually run this TestCase.
a polymophic address class
Definition address.h:90
A container for one type of attribute.
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
std::size_t GetWinSize() const
Get the window size.
uint16_t GetWinStart() const
Get the current winStart value.
uint16_t GetWinEnd() const
Get the current winEnd value.
std::vector< bool >::reference At(std::size_t distance)
Get a reference to the element in the window having the given distance from the current winStart.
Headers for BlockAck response.
void SetStartingSequence(uint16_t seq, std::size_t index=0)
For Block Ack variants other than Multi-STA Block Ack, set the starting sequence number to the given ...
bool IsPacketReceived(uint16_t seq, std::size_t index=0) const
Check if the packet with the given sequence number was acknowledged in this BlockAck response.
uint16_t GetStartingSequence(std::size_t index=0) const
For Block Ack variants other than Multi-STA Block Ack, get the starting sequence number.
Mac48Address GetUnassociatedStaAddress(std::size_t index) const
For Multi-STA Block Acks, get the RA subfield of the Per AID TID Info subfield (with AID11 subfield e...
uint8_t GetTidInfo(std::size_t index=0) const
For Block Ack variants other than Multi-STA Block Ack, get the TID_INFO subfield of the BA Control fi...
const std::vector< uint8_t > & GetBitmap(std::size_t index=0) const
Return a const reference to the bitmap from the BlockAck response header.
void ResetBitmap(std::size_t index=0)
Reset the bitmap to 0.
void SetType(BlockAckType type)
Set the block ack type.
BlockAckType GetType() const
Return the block ack type ID.
void SetReceivedPacket(uint16_t seq, std::size_t index=0)
Record in the bitmap that the packet with the given sequence number was received.
bool GetAckType(std::size_t index) const
For Multi-STA Block Acks, get the Ack Type subfield of the Per AID TID Info subfield identified by th...
uint16_t GetAid11(std::size_t index) const
For Multi-STA Block Acks, get the AID11 subfield of the Per AID TID Info subfield identified by the g...
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
void SetList(const std::list< uint64_t > &packetlist)
an EUI-48 address
static Mac48Address Allocate()
Allocate a new Mac48Address.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition node.cc:153
Maintains the state and information about transmitted MPDUs with Ack Policy set to Block Ack for an o...
void NotifyDiscardedMpdu(Ptr< const WifiMpdu > mpdu)
Advance the transmit window beyond the MPDU that has been reported to be discarded.
uint16_t GetStartingSequence() const override
Return the starting sequence number of the transmit window, if a transmit window has been initialized...
BlockAckWindow m_txWindow
originator's transmit window
void NotifyTransmittedMpdu(Ptr< const WifiMpdu > mpdu)
Advance the transmit window so as to include the transmitted MPDU, if the latter is not an old packet...
void NotifyAckedMpdu(Ptr< const WifiMpdu > mpdu)
Record that the given MPDU has been acknowledged and advance the transmit window if possible.
void InitTxWindow()
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
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.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Definition qos-txop.h:52
Maintains the scoreboard and the receive reordering buffer used by a recipient of a Block Ack agreeme...
void NotifyReceivedBar(uint16_t startingSequenceNumber)
Update both the scoreboard and the receive reordering buffer upon reception of a Block Ack Request.
void NotifyReceivedMpdu(Ptr< const WifiMpdu > mpdu)
Update both the scoreboard and the receive reordering buffer upon reception of the given MPDU.
void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
Implements the IEEE 802.11 MAC header.
bool IsBlockAckReq() const
Return true if the header is a BlockAckRequest header.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
bool IsBlockAck() const
Return true if the header is a BlockAck header.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
bool IsQosBlockAck() const
Return if the QoS Ack policy is Block Ack.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
create MAC layers for a ns3::WifiNetDevice.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Make it easy to create and manage PHY objects for the YANS model.
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:943
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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:986
#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:134
#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:780
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition test.h:946
#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:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
Definition qos-utils.cc:145
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ AC_BE
Best Effort.
Definition qos-utils.h:64
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
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:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
Definition phy-entity.h:45
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
Definition wifi-utils.h:176
Keeps the maximum duration among all TXOPs.
void Trace(Time startTime, Time duration, uint8_t linkId)
Callback for the TxopTrace trace.
The different BlockAck variants.
Variant m_variant
Block Ack variant.
std::vector< uint8_t > m_bitmapLen
Length (bytes) of included bitmaps.