A Discrete-Event Network Simulator
API
block-ack-test-suite.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2009, 2010 MIRKO BANCHI
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mirko Banchi <mk.banchi@gmail.com>
19 */
20
21#include "ns3/test.h"
22#include "ns3/double.h"
23#include "ns3/boolean.h"
24#include "ns3/string.h"
25#include "ns3/qos-utils.h"
26#include "ns3/ctrl-headers.h"
27#include "ns3/packet.h"
28#include "ns3/wifi-net-device.h"
29#include "ns3/ap-wifi-mac.h"
30#include "ns3/wifi-mac-header.h"
31#include "ns3/mobility-helper.h"
32#include "ns3/yans-wifi-helper.h"
33#include "ns3/packet-socket-server.h"
34#include "ns3/packet-socket-client.h"
35#include "ns3/packet-socket-helper.h"
36#include "ns3/config.h"
37#include "ns3/pointer.h"
38#include "ns3/recipient-block-ack-agreement.h"
39#include "ns3/mac-rx-middle.h"
40#include "ns3/qos-txop.h"
41#include "ns3/originator-block-ack-agreement.h"
42#include "ns3/wifi-mac-queue-item.h"
43#include <list>
44
45using namespace ns3;
46
61//-------------------------------------------------------------------------------------
62
63/* ----- = old packets
64 * +++++ = new packets
65 *
66 * CASE A: startSeq < endSeq
67 * - - +
68 * initial buffer state: 0 16 56000
69 *
70 *
71 * 0 4095
72 * |------|++++++++++++++++|-----|
73 * ^ ^
74 * | startSeq | endSeq = 4000
75 *
76 * first received packet's sequence control = 64016 (seqNum = 4001, fragNum = 0) -
77 * second received packet's sequence control = 63984 (seqNum = 3999, fragNum = 0) +
78 * 4001 is older seq number so this packet should be inserted at the buffer's begin.
79 * 3999 is previous element of older of new packets: it should be inserted at the end of buffer.
80 *
81 * expected buffer state: 64016 0 16 56000 63984
82 *
83 */
85{
86public:
88 virtual ~PacketBufferingCaseA ();
89private:
90 void DoRun (void) override;
91 std::list<uint16_t> m_expectedBuffer;
92};
93
95 : TestCase ("Check correct order of buffering when startSequence < endSeq")
96{
97 m_expectedBuffer.push_back (64016);
98 m_expectedBuffer.push_back (0);
99 m_expectedBuffer.push_back (16);
100 m_expectedBuffer.push_back (56000);
101 m_expectedBuffer.push_back (63984);
102}
103
105{
106}
107
108void
110{
111 std::list<uint16_t> m_buffer;
112 std::list<uint16_t>::iterator i,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
182{
183public:
185 virtual ~PacketBufferingCaseB ();
186private:
187 void DoRun (void) override;
188 std::list<uint16_t> m_expectedBuffer;
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
203{
204}
205
206void
208{
209 std::list<uint16_t> m_buffer;
210 std::list<uint16_t>::iterator i,j;
211 m_buffer.push_back (256);
212 m_buffer.push_back (64000);
213 m_buffer.push_back (16);
214
215 uint16_t endSeq = 10;
216
217 uint16_t receivedSeq = 15 * 16;
218 uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
219 /* cycle to right position for this packet */
220 for (i = m_buffer.begin (); i != m_buffer.end (); i++)
221 {
222 if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
223 {
224 //position found
225 break;
226 }
227 }
228 m_buffer.insert (i, receivedSeq);
229
230 receivedSeq = 15 * 16 + 1;
231 mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
232 /* cycle to right position for this packet */
233 for (i = m_buffer.begin (); i != m_buffer.end (); i++)
234 {
235 if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
236 {
237 //position found
238 break;
239 }
240 }
241 m_buffer.insert (i, receivedSeq);
242
243 receivedSeq = 4050 * 16;
244 mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
245 /* cycle to right position for this packet */
246 for (i = m_buffer.begin (); i != m_buffer.end (); i++)
247 {
248 if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
249 {
250 //position found
251 break;
252 }
253 }
254 m_buffer.insert (i, receivedSeq);
255
256 for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
257 {
258 NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
259 }
260}
261
269{
270public:
272private:
273 void DoRun (void) override;
274};
275
277 : TestCase ("Check the correctness of the originator block ack window")
278{
279}
280
281void
283{
284 uint16_t winSize = 16;
285 uint16_t startingSeq = 4090;
286
287 OriginatorBlockAckAgreement agreement (Mac48Address ("00:00:00:00:00:01"), 0);
288 agreement.SetBufferSize (winSize);
289 agreement.SetStartingSequence (startingSeq);
290 agreement.InitTxWindow ();
291
292 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.GetWinSize (), winSize, "Incorrect window size");
293 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.GetWinStart (), startingSeq, "Incorrect winStart");
294 // check that all the elements in the window are cleared
295 for (uint16_t i = 0; i < winSize; i++)
296 {
297 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Not all flags are cleared after initialization");
298 }
299
300 // Notify the acknowledgment of 5 packets
301 WifiMacHeader hdr;
303 Ptr<WifiMacQueueItem> mpdu = Create<WifiMacQueueItem> (Create<Packet> (), hdr);
304 uint16_t seqNumber = startingSeq;
305 mpdu->GetHeader ().SetSequenceNumber (seqNumber);
306 agreement.NotifyAckedMpdu (mpdu);
307
308 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
309 agreement.NotifyAckedMpdu (mpdu);
310
311 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
312 agreement.NotifyAckedMpdu (mpdu);
313
314 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
315 agreement.NotifyAckedMpdu (mpdu);
316
317 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
318 agreement.NotifyAckedMpdu (mpdu);
319
320 // the current window must look like this:
321 //
322 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
323 // ^
324 // |
325 // HEAD
326
327 startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
328 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after 5 acknowledgments");
329 for (uint16_t i = 0; i < winSize; i++)
330 {
331 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Not all flags are cleared after 5 acknowledgments");
332 }
333
334 // the next MPDU is not acknowledged, hence the window is blocked while the
335 // subsequent 4 MPDUs are acknowledged
336 ++seqNumber %= SEQNO_SPACE_SIZE;
337 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
338 agreement.NotifyAckedMpdu (mpdu);
339
340 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
341 agreement.NotifyAckedMpdu (mpdu);
342
343 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
344 agreement.NotifyAckedMpdu (mpdu);
345
346 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
347 agreement.NotifyAckedMpdu (mpdu);
348
349 // the current window must look like this:
350 //
351 // |0|0|0|0|0|0|1|1|1|1|0|0|0|0|0|0|
352 // ^
353 // |
354 // HEAD
355
356 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after 1 unacknowledged MPDU");
357 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after 1 unacknowledged MPDU");
358 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), true, "Incorrect flag after 1 unacknowledged MPDU");
359 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), true, "Incorrect flag after 1 unacknowledged MPDU");
360 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after 1 unacknowledged MPDU");
361 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after 1 unacknowledged MPDU");
362 for (uint16_t i = 5; i < winSize; i++)
363 {
364 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after 1 unacknowledged MPDU");
365 }
366
367 // the missing MPDU is now acknowledged; the window moves forward and the starting
368 // sequence number is the one of the first unacknowledged MPDU
369 mpdu->GetHeader ().SetSequenceNumber (startingSeq);
370 agreement.NotifyAckedMpdu (mpdu);
371
372 // the current window must look like this:
373 //
374 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
375 // ^
376 // |
377 // HEAD
378
379 startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
380 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after acknowledgment of missing MPDU");
381 for (uint16_t i = 0; i < winSize; i++)
382 {
383 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Not all flags are cleared after acknowledgment of missing MPDU");
384 }
385
386 // Now, create a hole of 3 MPDUs before 4 acknowledged MPDUs, another hole of 2 MPDUs before 3 acknowledged MPDUs
387 seqNumber = (seqNumber + 4) % SEQNO_SPACE_SIZE;
388 mpdu->GetHeader ().SetSequenceNumber (seqNumber);
389 agreement.NotifyAckedMpdu (mpdu);
390
391 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
392 agreement.NotifyAckedMpdu (mpdu);
393
394 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
395 agreement.NotifyAckedMpdu (mpdu);
396
397 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
398 agreement.NotifyAckedMpdu (mpdu);
399
400 seqNumber = (seqNumber + 3) % SEQNO_SPACE_SIZE;
401 mpdu->GetHeader ().SetSequenceNumber (seqNumber);
402 agreement.NotifyAckedMpdu (mpdu);
403
404 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
405 agreement.NotifyAckedMpdu (mpdu);
406
407 mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
408 agreement.NotifyAckedMpdu (mpdu);
409
410 // the current window must look like this:
411 //
412 // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
413 // ^
414 // |
415 // HEAD
416
417 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after 3 unacknowledged MPDUs");
418 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after 3 unacknowledged MPDUs");
419 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), false, "Incorrect flag after 3 unacknowledged MPDUs");
420 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), false, "Incorrect flag after 3 unacknowledged MPDUs");
421 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after 3 unacknowledged MPDUs");
422 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after 3 unacknowledged MPDUs");
423 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (5), true, "Incorrect flag after 3 unacknowledged MPDUs");
424 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (6), true, "Incorrect flag after 3 unacknowledged MPDUs");
425 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (7), false, "Incorrect flag after 3 unacknowledged MPDUs");
426 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (8), false, "Incorrect flag after 3 unacknowledged MPDUs");
427 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (9), true, "Incorrect flag after 3 unacknowledged MPDUs");
428 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (10), true, "Incorrect flag after 3 unacknowledged MPDUs");
429 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (11), true, "Incorrect flag after 3 unacknowledged MPDUs");
430 for (uint16_t i = 12; i < winSize; i++)
431 {
432 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after 3 unacknowledged MPDUs");
433 }
434
435 // the transmission of an MPDU beyond the current window (by 2 positions) is
436 // notified, hence the window moves forward 2 positions
437 seqNumber = (agreement.m_txWindow.GetWinEnd () + 2) % SEQNO_SPACE_SIZE;
438 mpdu->GetHeader ().SetSequenceNumber (seqNumber);
439 agreement.NotifyTransmittedMpdu (mpdu);
440
441 // the current window must look like this:
442 //
443 // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
444 // ^
445 // |
446 // HEAD
447
448 startingSeq = (startingSeq + 2) % SEQNO_SPACE_SIZE;
449 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
450 "Incorrect starting sequence after transmitting an MPDU beyond the current window");
451 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after transmitting an MPDU beyond the current window");
452 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), true, "Incorrect flag after transmitting an MPDU beyond the current window");
453 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), true, "Incorrect flag after transmitting an MPDU beyond the current window");
454 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after transmitting an MPDU beyond the current window");
455 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after transmitting an MPDU beyond the current window");
456 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (5), false, "Incorrect flag after transmitting an MPDU beyond the current window");
457 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (6), false, "Incorrect flag after transmitting an MPDU beyond the current window");
458 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (7), true, "Incorrect flag after transmitting an MPDU beyond the current window");
459 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (8), true, "Incorrect flag after transmitting an MPDU beyond the current window");
460 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (9), true, "Incorrect flag after transmitting an MPDU beyond the current window");
461 for (uint16_t i = 10; i < winSize; i++)
462 {
463 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after transmitting an MPDU beyond the current window");
464 }
465
466 // another MPDU is transmitted beyond the current window. Now, the window advances
467 // until the first unacknowledged MPDU
468 seqNumber = (agreement.m_txWindow.GetWinEnd () + 1) % SEQNO_SPACE_SIZE;
469 mpdu->GetHeader ().SetSequenceNumber (seqNumber);
470 agreement.NotifyTransmittedMpdu (mpdu);
471
472 // the current window must look like this:
473 //
474 // |0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|
475 // ^
476 // |
477 // HEAD
478
479 startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
480 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
481 "Incorrect starting sequence after transmitting another MPDU beyond the current window");
482 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after transmitting another MPDU beyond the current window");
483 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), false, "Incorrect flag after transmitting another MPDU beyond the current window");
484 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), true, "Incorrect flag after transmitting another MPDU beyond the current window");
485 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after transmitting another MPDU beyond the current window");
486 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after transmitting another MPDU beyond the current window");
487 for (uint16_t i = 5; i < winSize; i++)
488 {
489 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after transmitting another MPDU beyond the current window");
490 }
491
492 // the MPDU next to winStart is discarded, hence the window advances to make it an old packet.
493 // Since the subsequent MPDUs have been acknowledged, the window advances further.
494 seqNumber = (startingSeq + 1) % SEQNO_SPACE_SIZE;
495 mpdu->GetHeader ().SetSequenceNumber (seqNumber);
496 agreement.NotifyDiscardedMpdu (mpdu);
497
498 // the current window must look like this:
499 //
500 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
501 // ^
502 // |
503 // HEAD
504
505 startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
506 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
507 "Incorrect starting sequence after discarding an MPDU");
508 for (uint16_t i = 0; i < winSize; i++)
509 {
510 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after discarding an MPDU");
511 }
512
513 // Finally, check that the window correctly advances when the MPDU with the starting sequence number
514 // is acknowledged after being the only unacknowledged MPDU
515 for (uint16_t i = 1; i < winSize; i++)
516 {
517 mpdu->GetHeader ().SetSequenceNumber ((startingSeq + i) % SEQNO_SPACE_SIZE);
518 agreement.NotifyAckedMpdu (mpdu);
519 }
520
521 // the current window must look like this:
522 //
523 // |1|1|1|1|1|1|0|1|1|1|1|1|1|1|1|1|
524 // ^
525 // |
526 // HEAD
527
528 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
529 "Incorrect starting sequence after acknowledging all but the first MPDU");
530 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after acknowledging all but the first MPDU");
531 for (uint16_t i = 1; i < winSize; i++)
532 {
533 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), true, "Incorrect flag after acknowledging all but the first MPDU");
534 }
535
536 // acknowledge the first MPDU
537 mpdu->GetHeader ().SetSequenceNumber (startingSeq % SEQNO_SPACE_SIZE);
538 agreement.NotifyAckedMpdu (mpdu);
539
540 // the current window must look like this:
541 //
542 // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
543 // ^
544 // |
545 // HEAD
546
547 startingSeq = (startingSeq + winSize) % SEQNO_SPACE_SIZE;
548 NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
549 "Incorrect starting sequence after acknowledging the first MPDU");
550 for (uint16_t i = 0; i < winSize; i++)
551 {
552 NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after acknowledging the first MPDU");
553 }
554}
555
556
564{
565public:
567private:
568 void DoRun (void) override;
570};
571
573 : TestCase ("Check the correctness of block ack compressed bitmap")
574{
575}
576
577void
579{
580 m_blockAckHdr.SetType (BlockAckType::COMPRESSED);
581
582 //Case 1: startSeq < endSeq
583 // 179 242
585 for (uint16_t i = 179; i < 220; i++)
586 {
588 }
589 for (uint16_t i = 225; i <= 242; i++)
590 {
592 }
593 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
594 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
595 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0xff, "error in compressed bitmap");
596 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0xff, "error in compressed bitmap");
597 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0xff, "error in compressed bitmap");
598 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0xc1, "error in compressed bitmap");
599 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0xff, "error in compressed bitmap");
600 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0xff, "error in compressed bitmap");
602 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
603 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
604 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0xff, "error in compressed bitmap");
605 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0xff, "error in compressed bitmap");
606 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0xff, "error in compressed bitmap");
607 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0xc1, "error in compressed bitmap");
608 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0xff, "error in compressed bitmap");
609 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0xff, "error in compressed bitmap");
610 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (220), false, "error in compressed bitmap");
611 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (225), true, "error in compressed bitmap");
612 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (1500), false, "error in compressed bitmap");
613
615
616 //Case 2: startSeq > endSeq
617 // 4090 58
619 for (uint16_t i = 4090; i != 10; i = (i + 1) % 4096)
620 {
622 }
623 for (uint16_t i = 22; i < 25; i++)
624 {
626 }
627 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
628 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
629 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0x00, "error in compressed bitmap");
630 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0x70, "error in compressed bitmap");
631 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0x00, "error in compressed bitmap");
632 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0x00, "error in compressed bitmap");
633 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0x00, "error in compressed bitmap");
634 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0x00, "error in compressed bitmap");
636 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
637 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
638 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0x00, "error in compressed bitmap");
639 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0x70, "error in compressed bitmap");
640 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0x00, "error in compressed bitmap");
641 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0x00, "error in compressed bitmap");
642 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0x00, "error in compressed bitmap");
643 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0x00, "error in compressed bitmap");
644 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (4090), true, "error in compressed bitmap");
645 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (4095), true, "error in compressed bitmap");
646 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (10), false, "error in compressed bitmap");
647 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (35), false, "error in compressed bitmap");
648 NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (80), false, "error in compressed bitmap");
649}
650
651
659{
660public:
665 BlockAckRecipientBufferTest (uint16_t ssn);
667
668 void DoRun (void) override;
669
676 void ForwardUp (Ptr<WifiMacQueueItem> mpdu, uint8_t linkId);
677
678private:
679 uint16_t m_ssn;
680 std::list<Ptr<WifiMacQueueItem>> m_fwup;
681};
682
684 : TestCase ("Test case for Block Ack recipient reordering buffer operations"),
685 m_ssn (ssn)
686{
687}
688
690{
691}
692
693void
695{
696 m_fwup.push_back (mpdu);
697}
698
699void
701{
702 Ptr<MacRxMiddle> rxMiddle = Create<MacRxMiddle> ();
703 rxMiddle->SetForwardCallback (MakeCallback (&BlockAckRecipientBufferTest::ForwardUp, this));
704
705 RecipientBlockAckAgreement agreement (Mac48Address::Allocate () /* originator */,
706 true /* amsduSupported */, 0 /* tid */, 10 /* bufferSize */,
707 0 /* timeout */, m_ssn, true /* htSupported */);
708 agreement.SetMacRxMiddle (rxMiddle);
709
710 WifiMacHeader hdr;
712 hdr.SetAddr1 (Mac48Address::Allocate ());
713 hdr.SetQosTid (0);
714
715 // Notify the reception of an MPDU with SN = SSN.
717 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
718
719 // This MPDU is forwarded up and WinStartB is set to SSN + 1.
720 NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 1, "MPDU with SN=SSN must have been forwarded up");
721 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (), m_ssn,
722 "The MPDU forwarded up is not the expected one");
723
724 m_fwup.clear ();
725
726 // Notify the reception of MPDUs with SN = SSN + {4, 2, 5, 3, 10, 7}
727 // Recipient buffer: | |X|X|X|X| |X| | |X|
728 // ^
729 // |
730 // SSN + 1
732 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
734 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
736 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
738 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
740 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
742 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
743
744 // No MPDU is forwarded up because the one with SN = SSN + 1 is missing
745 NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
746
747 // Notify the reception of an "old" MPDU (SN = SSN)
749 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
750
751 // No MPDU is forwarded up
752 NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
753
754 // Notify the reception of a duplicate MPDU (SN = SSN + 2)
756 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(10), hdr));
757
758 // No MPDU is forwarded up
759 NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
760
761 // Notify the reception of an MPDU with SN = SSN + 1
762 // Recipient buffer: |X|X|X|X|X| |X| | |X|
763 // ^
764 // |
765 // SSN + 1
767 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
768
769 // All the MPDUs with SN = SSN + {1, 2, 3, 4, 5} must have been forwarded up in order
770 NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 5, "5 MPDUs must have been forwarded up");
771
772 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
773 (m_ssn + 1) % SEQNO_SPACE_SIZE,
774 "The MPDU forwarded up is not the expected one");
775 m_fwup.pop_front ();
776
777 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
778 (m_ssn + 2) % SEQNO_SPACE_SIZE,
779 "The MPDU forwarded up is not the expected one");
780 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetPacketSize (), 0,
781 "The MPDU forwarded up is not the expected one");
782 m_fwup.pop_front ();
783
784 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
785 (m_ssn + 3) % SEQNO_SPACE_SIZE,
786 "The MPDU forwarded up is not the expected one");
787 m_fwup.pop_front ();
788
789 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
790 (m_ssn + 4) % SEQNO_SPACE_SIZE,
791 "The MPDU forwarded up is not the expected one");
792 m_fwup.pop_front ();
793
794 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
795 (m_ssn + 5) % SEQNO_SPACE_SIZE,
796 "The MPDU forwarded up is not the expected one");
797 m_fwup.pop_front ();
798
799 // Recipient buffer: | |X| | |X| | | | | |
800 // ^ ^
801 // | |
802 // SSN + 6 SSN + 15
803 // Notify the reception of an MPDU beyond the current window (SN = SSN + 17)
805 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
806
807 // WinStartB is set to SSN + 8 (so that WinEndB = SSN + 17). The MPDU with
808 // SN = SSN + 7 is forwarded up, irrespective of the missed reception of the
809 // MPDU with SN = SSN + 6
810 NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 1, "One MPDU must have been forwarded up");
811
812 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
813 (m_ssn + 7) % SEQNO_SPACE_SIZE,
814 "The MPDU forwarded up is not the expected one");
815 m_fwup.pop_front ();
816
817 // Recipient buffer: | | |X| | | | | | |X|
818 // ^ ^
819 // | |
820 // SSN + 8 SSN + 17
821 // Notify the reception of a BlockAckReq with SSN = SSN + 7
822 agreement.NotifyReceivedBar ((m_ssn + 7) % SEQNO_SPACE_SIZE);
823
824 // No MPDU is forwarded up
825 NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
826
827 // Notify the reception of a BlockAckReq with SSN = SSN + 8
828 agreement.NotifyReceivedBar ((m_ssn + 8) % SEQNO_SPACE_SIZE);
829
830 // No MPDU is forwarded up
831 NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
832
833 // Notify the reception of MPDUs with SN = SSN + {9, 11}
834 // Recipient buffer: | |X|X|X| | | | | |X|
835 // ^ ^
836 // | |
837 // SSN + 8 SSN + 17
839 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
841 agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
842
843 // No MPDU is forwarded up because the one with SN = SSN + 8 is missing
844 NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
845
846 // Notify the reception of a BlockAckReq with SSN = SSN + 10
847 agreement.NotifyReceivedBar ((m_ssn + 10) % SEQNO_SPACE_SIZE);
848
849 // Forward up buffered MPDUs with SN < SSN + 10 (the MPDU with SN = SSN + 9)
850 // and then buffered MPDUs with SN >= SSN + 10 until a hole is found (MPDUs
851 // with SN = SSN + 10 and SN = SSN + 11)
852 NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 3, "3 MPDUs must have been forwarded up");
853
854 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
855 (m_ssn + 9) % SEQNO_SPACE_SIZE,
856 "The MPDU forwarded up is not the expected one");
857 m_fwup.pop_front ();
858
859 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
860 (m_ssn + 10) % SEQNO_SPACE_SIZE,
861 "The MPDU forwarded up is not the expected one");
862 m_fwup.pop_front ();
863
864 NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
865 (m_ssn + 11) % SEQNO_SPACE_SIZE,
866 "The MPDU forwarded up is not the expected one");
867 m_fwup.pop_front ();
868
870 Simulator::Destroy ();
871}
872
873
881{
882public:
884private:
885 virtual void DoRun (void);
886};
887
889 : TestCase ("Check the correctness of Multi-STA block ack")
890{
891}
892
893void
895{
896 // Create a Multi-STA Block Ack with 6 Per AID TID Info subfields
897 BlockAckType baType (BlockAckType::MULTI_STA, {0, 4, 8, 16, 32, 8});
898
899 CtrlBAckResponseHeader blockAck;
900 blockAck.SetType (baType);
901
902 /* 1st Per AID TID Info subfield */
903 uint16_t aid1 = 100;
904 bool ackType1 = true;
905 uint8_t tid1 = 1;
906
907 blockAck.SetAid11 (aid1, 0);
908 blockAck.SetAckType (ackType1, 0);
909 blockAck.SetTidInfo (tid1, 0);
910
911 /* 2nd Per AID TID Info subfield */
912 uint16_t aid2 = 200;
913 bool ackType2 = false;
914 uint8_t tid2 = 2;
915 uint16_t startSeq2 = 1000;
916
917 blockAck.SetAid11 (aid2, 1);
918 blockAck.SetAckType (ackType2, 1);
919 blockAck.SetTidInfo (tid2, 1);
920 blockAck.SetStartingSequence (startSeq2, 1);
921 // 1st byte of the bitmap: 01010101
922 for (uint16_t i = startSeq2; i < startSeq2 + 8; i+=2)
923 {
924 blockAck.SetReceivedPacket (i, 1);
925 }
926 // 2nd byte of the bitmap: 10101010
927 for (uint16_t i = startSeq2 + 9; i < startSeq2 + 16; i+=2)
928 {
929 blockAck.SetReceivedPacket (i, 1);
930 }
931 // 3rd byte of the bitmap: 00000000
932 // 4th byte of the bitmap: 11111111
933 for (uint16_t i = startSeq2 + 24; i < startSeq2 + 32; i++)
934 {
935 blockAck.SetReceivedPacket (i, 1);
936 }
937
938 /* 3rd Per AID TID Info subfield */
939 uint16_t aid3 = 300;
940 bool ackType3 = false;
941 uint8_t tid3 = 3;
942 uint16_t startSeq3 = 2000;
943
944 blockAck.SetAid11 (aid3, 2);
945 blockAck.SetAckType (ackType3, 2);
946 blockAck.SetTidInfo (tid3, 2);
947 blockAck.SetStartingSequence (startSeq3, 2);
948 // 1st byte of the bitmap: 01010101
949 for (uint16_t i = startSeq3; i < startSeq3 + 8; i+=2)
950 {
951 blockAck.SetReceivedPacket (i, 2);
952 }
953 // 2nd byte of the bitmap: 10101010
954 for (uint16_t i = startSeq3 + 9; i < startSeq3 + 16; i+=2)
955 {
956 blockAck.SetReceivedPacket (i, 2);
957 }
958 // 3rd byte of the bitmap: 00000000
959 // 4th byte of the bitmap: 11111111
960 for (uint16_t i = startSeq3 + 24; i < startSeq3 + 32; i++)
961 {
962 blockAck.SetReceivedPacket (i, 2);
963 }
964 // 5th byte of the bitmap: 00001111
965 for (uint16_t i = startSeq3 + 32; i < startSeq3 + 36; i++)
966 {
967 blockAck.SetReceivedPacket (i, 2);
968 }
969 // 6th byte of the bitmap: 11110000
970 for (uint16_t i = startSeq3 + 44; i < startSeq3 + 48; i++)
971 {
972 blockAck.SetReceivedPacket (i, 2);
973 }
974 // 7th byte of the bitmap: 00000000
975 // 8th byte of the bitmap: 11111111
976 for (uint16_t i = startSeq3 + 56; i < startSeq3 + 64; i++)
977 {
978 blockAck.SetReceivedPacket (i, 2);
979 }
980
981 /* 4th Per AID TID Info subfield */
982 uint16_t aid4 = 400;
983 bool ackType4 = false;
984 uint8_t tid4 = 4;
985 uint16_t startSeq4 = 3000;
986
987 blockAck.SetAid11 (aid4, 3);
988 blockAck.SetAckType (ackType4, 3);
989 blockAck.SetTidInfo (tid4, 3);
990 blockAck.SetStartingSequence (startSeq4, 3);
991 // 1st byte of the bitmap: 01010101
992 for (uint16_t i = startSeq4; i < startSeq4 + 8; i+=2)
993 {
994 blockAck.SetReceivedPacket (i, 3);
995 }
996 // 2nd byte of the bitmap: 10101010
997 for (uint16_t i = startSeq4 + 9; i < startSeq4 + 16; i+=2)
998 {
999 blockAck.SetReceivedPacket (i, 3);
1000 }
1001 // 3rd byte of the bitmap: 00000000
1002 // 4th byte of the bitmap: 11111111
1003 for (uint16_t i = startSeq4 + 24; i < startSeq4 + 32; i++)
1004 {
1005 blockAck.SetReceivedPacket (i, 3);
1006 }
1007 // 5th byte of the bitmap: 00001111
1008 for (uint16_t i = startSeq4 + 32; i < startSeq4 + 36; i++)
1009 {
1010 blockAck.SetReceivedPacket (i, 3);
1011 }
1012 // 6th byte of the bitmap: 11110000
1013 for (uint16_t i = startSeq4 + 44; i < startSeq4 + 48; i++)
1014 {
1015 blockAck.SetReceivedPacket (i, 3);
1016 }
1017 // 7th byte of the bitmap: 00000000
1018 // 8th byte of the bitmap: 11111111
1019 for (uint16_t i = startSeq4 + 56; i < startSeq4 + 64; i++)
1020 {
1021 blockAck.SetReceivedPacket (i, 3);
1022 }
1023 // 9th byte of the bitmap: 00000000
1024 // 10th byte of the bitmap: 11111111
1025 for (uint16_t i = startSeq4 + 72; i < startSeq4 + 80; i++)
1026 {
1027 blockAck.SetReceivedPacket (i, 3);
1028 }
1029 // 11th byte of the bitmap: 00000000
1030 // 12th byte of the bitmap: 11111111
1031 for (uint16_t i = startSeq4 + 88; i < startSeq4 + 96; i++)
1032 {
1033 blockAck.SetReceivedPacket (i, 3);
1034 }
1035 // 13th byte of the bitmap: 00000000
1036 // 14th byte of the bitmap: 11111111
1037 for (uint16_t i = startSeq4 + 104; i < startSeq4 + 112; i++)
1038 {
1039 blockAck.SetReceivedPacket (i, 3);
1040 }
1041 // 15th byte of the bitmap: 00000000
1042 // 16th byte of the bitmap: 11111111
1043 for (uint16_t i = startSeq4 + 120; i < startSeq4 + 128; i++)
1044 {
1045 blockAck.SetReceivedPacket (i, 3);
1046 }
1047
1048 /* 5th Per AID TID Info subfield */
1049 uint16_t aid5 = 500;
1050 bool ackType5 = false;
1051 uint8_t tid5 = 5;
1052 uint16_t startSeq5 = 4000;
1053
1054 blockAck.SetAid11 (aid5, 4);
1055 blockAck.SetAckType (ackType5, 4);
1056 blockAck.SetTidInfo (tid5, 4);
1057 blockAck.SetStartingSequence (startSeq5, 4);
1058 // 1st byte of the bitmap: 01010101
1059 for (uint16_t i = startSeq5; i < startSeq5 + 8; i+=2)
1060 {
1061 blockAck.SetReceivedPacket (i, 4);
1062 }
1063 // 2nd byte of the bitmap: 10101010
1064 for (uint16_t i = startSeq5 + 9; i < startSeq5 + 16; i+=2)
1065 {
1066 blockAck.SetReceivedPacket (i, 4);
1067 }
1068 // 3rd byte of the bitmap: 00000000
1069 // 4th byte of the bitmap: 11111111
1070 for (uint16_t i = startSeq5 + 24; i < startSeq5 + 32; i++)
1071 {
1072 blockAck.SetReceivedPacket (i, 4);
1073 }
1074 // 5th byte of the bitmap: 00001111
1075 for (uint16_t i = startSeq5 + 32; i < startSeq5 + 36; i++)
1076 {
1077 blockAck.SetReceivedPacket (i, 4);
1078 }
1079 // 6th byte of the bitmap: 11110000
1080 for (uint16_t i = startSeq5 + 44; i < startSeq5 + 48; i++)
1081 {
1082 blockAck.SetReceivedPacket (i, 4);
1083 }
1084 // 7th byte of the bitmap: 00000000
1085 // 8th byte of the bitmap: 11111111
1086 for (uint16_t i = startSeq5 + 56; i < startSeq5 + 64; i++)
1087 {
1088 blockAck.SetReceivedPacket (i, 4);
1089 }
1090 // 9th byte of the bitmap: 00000000
1091 // 10th byte of the bitmap: 11111111
1092 for (uint16_t i = startSeq5 + 72; i < startSeq5 + 80; i++)
1093 {
1094 blockAck.SetReceivedPacket (i, 4);
1095 }
1096 // 11th byte of the bitmap: 00000000
1097 // 12th byte of the bitmap: 11111111
1098 for (uint16_t i = startSeq5 + 88; i < startSeq5 + 96; i++)
1099 {
1100 blockAck.SetReceivedPacket (i, 4);
1101 }
1102 // 13th byte of the bitmap: 00000000
1103 // 14th byte of the bitmap: 11111111
1104 for (uint16_t i = (startSeq5 + 104) % 4096; i < (startSeq5 + 112) % 4096; i++)
1105 {
1106 blockAck.SetReceivedPacket (i, 4);
1107 }
1108 // 15th byte of the bitmap: 00000000
1109 // 16th byte of the bitmap: 11111111
1110 for (uint16_t i = (startSeq5 + 120) % 4096; i < (startSeq5 + 128) % 4096; i++)
1111 {
1112 blockAck.SetReceivedPacket (i, 4);
1113 }
1114 // 17th byte of the bitmap: 00000000
1115 // 18th byte of the bitmap: 11111111
1116 for (uint16_t i = (startSeq5 + 136) % 4096; i < (startSeq5 + 144) % 4096; i++)
1117 {
1118 blockAck.SetReceivedPacket (i, 4);
1119 }
1120 // 19th byte of the bitmap: 00000000
1121 // 20th byte of the bitmap: 11111111
1122 for (uint16_t i = (startSeq5 + 152) % 4096; i < (startSeq5 + 160) % 4096; i++)
1123 {
1124 blockAck.SetReceivedPacket (i, 4);
1125 }
1126 // 21th byte of the bitmap: 00000000
1127 // 22th byte of the bitmap: 11111111
1128 for (uint16_t i = (startSeq5 + 168) % 4096; i < (startSeq5 + 176) % 4096; i++)
1129 {
1130 blockAck.SetReceivedPacket (i, 4);
1131 }
1132 // 23th byte of the bitmap: 00000000
1133 // 24th byte of the bitmap: 11111111
1134 for (uint16_t i = (startSeq5 + 184) % 4096; i < (startSeq5 + 192) % 4096; i++)
1135 {
1136 blockAck.SetReceivedPacket (i, 4);
1137 }
1138 // 25th byte of the bitmap: 00000000
1139 // 26th byte of the bitmap: 11111111
1140 for (uint16_t i = (startSeq5 + 200) % 4096; i < (startSeq5 + 208) % 4096; i++)
1141 {
1142 blockAck.SetReceivedPacket (i, 4);
1143 }
1144 // 27th byte of the bitmap: 00000000
1145 // 28th byte of the bitmap: 11111111
1146 for (uint16_t i = (startSeq5 + 216) % 4096; i < (startSeq5 + 224) % 4096; i++)
1147 {
1148 blockAck.SetReceivedPacket (i, 4);
1149 }
1150 // 29th byte of the bitmap: 00000000
1151 // 30th byte of the bitmap: 11111111
1152 for (uint16_t i = (startSeq5 + 232) % 4096; i < (startSeq5 + 240) % 4096; i++)
1153 {
1154 blockAck.SetReceivedPacket (i, 4);
1155 }
1156 // 31th byte of the bitmap: 00000000
1157 // 32th byte of the bitmap: 11111111
1158 for (uint16_t i = (startSeq5 + 248) % 4096; i < (startSeq5 + 256) % 4096; i++)
1159 {
1160 blockAck.SetReceivedPacket (i, 4);
1161 }
1162
1163 /* 6th Per AID TID Info subfield */
1164 uint16_t aid6 = 2045;
1165 bool ackType6 = true;
1166 uint8_t tid6 = 6;
1167 Mac48Address address6 = Mac48Address ("00:00:00:00:00:01");
1168
1169 blockAck.SetAid11 (aid6, 5);
1170 blockAck.SetAckType (ackType6, 5);
1171 blockAck.SetTidInfo (tid6, 5);
1172 blockAck.SetUnassociatedStaAddress (address6, 5);
1173
1174 // Serialize the header
1175 Ptr<Packet> packet = Create<Packet> ();
1176 packet->AddHeader (blockAck);
1177
1178 // Deserialize the header
1179 CtrlBAckResponseHeader blockAckCopy;
1180 packet->RemoveHeader (blockAckCopy);
1181
1182 // Check that the header has been correctly deserialized
1183 BlockAckType baTypeCopy = blockAckCopy.GetType ();
1184
1185 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_variant, BlockAckType::MULTI_STA, "Different block ack variant");
1186 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen.size (), 6, "Different number of bitmaps");
1187 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen[0], 0, "Different length of the first bitmap");
1188 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen[1], 4, "Different length of the second bitmap");
1189 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen[2], 8, "Different length of the third bitmap");
1190 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen[3], 16, "Different length of the fourth bitmap");
1191 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen[4], 32, "Different length of the fifth bitmap");
1192 NS_TEST_EXPECT_MSG_EQ (baTypeCopy.m_bitmapLen[5], 8, "Different length for the sixth bitmap");
1193
1194 /* Check 1st Per AID TID Info subfield */
1195 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAid11 (0), aid1, "Different AID for the first Per AID TID Info subfield");
1196 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAckType (0), ackType1, "Different Ack Type for the first Per AID TID Info subfield");
1197 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetTidInfo (0), tid1, "Different TID for the first Per AID TID Info subfield");
1198
1199 /* Check 2nd Per AID TID Info subfield */
1200 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAid11 (1), aid2, "Different AID for the second Per AID TID Info subfield");
1201 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAckType (1), ackType2, "Different Ack Type for the second Per AID TID Info subfield");
1202 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetTidInfo (1), tid2, "Different TID for the second Per AID TID Info subfield");
1203 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetStartingSequence (1), startSeq2, "Different starting sequence number for the second Per AID TID Info subfield");
1204
1205 auto& bitmap2 = blockAckCopy.GetBitmap (1);
1206 NS_TEST_EXPECT_MSG_EQ (bitmap2.size (), 4, "Different bitmap length for the second Per AID TID Info subfield");
1207 NS_TEST_EXPECT_MSG_EQ (bitmap2[0], 0x55, "Error in the 1st byte of the bitmap for the second Per AID TID Info subfield");
1208 NS_TEST_EXPECT_MSG_EQ (bitmap2[1], 0xaa, "Error in the 2nd byte of the bitmap for the second Per AID TID Info subfield");
1209 NS_TEST_EXPECT_MSG_EQ (bitmap2[2], 0x00, "Error in the 3rd byte of the bitmap for the second Per AID TID Info subfield");
1210 NS_TEST_EXPECT_MSG_EQ (bitmap2[3], 0xff, "Error in the 4th byte of the bitmap for the second Per AID TID Info subfield");
1211
1212 /* Check 3rd Per AID TID Info subfield */
1213 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAid11 (2), aid3, "Different AID for the third Per AID TID Info subfield");
1214 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAckType (2), ackType3, "Different Ack Type for the third Per AID TID Info subfield");
1215 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetTidInfo (2), tid3, "Different TID for the third Per AID TID Info subfield");
1216 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetStartingSequence (2), startSeq3, "Different starting sequence number for the third Per AID TID Info subfield");
1217
1218 auto& bitmap3 = blockAckCopy.GetBitmap (2);
1219 NS_TEST_EXPECT_MSG_EQ (bitmap3.size (), 8, "Different bitmap length for the third Per AID TID Info subfield");
1220 NS_TEST_EXPECT_MSG_EQ (bitmap3[0], 0x55, "Error in the 1st byte of the bitmap for the third Per AID TID Info subfield");
1221 NS_TEST_EXPECT_MSG_EQ (bitmap3[1], 0xaa, "Error in the 2nd byte of the bitmap for the third Per AID TID Info subfield");
1222 NS_TEST_EXPECT_MSG_EQ (bitmap3[2], 0x00, "Error in the 3rd byte of the bitmap for the third Per AID TID Info subfield");
1223 NS_TEST_EXPECT_MSG_EQ (bitmap3[3], 0xff, "Error in the 4th byte of the bitmap for the third Per AID TID Info subfield");
1224 NS_TEST_EXPECT_MSG_EQ (bitmap3[4], 0x0f, "Error in the 5th byte of the bitmap for the third Per AID TID Info subfield");
1225 NS_TEST_EXPECT_MSG_EQ (bitmap3[5], 0xf0, "Error in the 6th byte of the bitmap for the third Per AID TID Info subfield");
1226 NS_TEST_EXPECT_MSG_EQ (bitmap3[6], 0x00, "Error in the 7th byte of the bitmap for the third Per AID TID Info subfield");
1227 NS_TEST_EXPECT_MSG_EQ (bitmap3[7], 0xff, "Error in the 8th byte of the bitmap for the third Per AID TID Info subfield");
1228
1229 /* Check 4th Per AID TID Info subfield */
1230 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAid11 (3), aid4, "Different AID for the fourth Per AID TID Info subfield");
1231 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAckType (3), ackType4, "Different Ack Type for the fourth Per AID TID Info subfield");
1232 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetTidInfo (3), tid4, "Different TID for the fourth Per AID TID Info subfield");
1233 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetStartingSequence (3), startSeq4, "Different starting sequence number for the fourth Per AID TID Info subfield");
1234
1235 auto& bitmap4 = blockAckCopy.GetBitmap (3);
1236 NS_TEST_EXPECT_MSG_EQ (bitmap4.size (), 16, "Different bitmap length for the fourth Per AID TID Info subfield");
1237 NS_TEST_EXPECT_MSG_EQ (bitmap4[0], 0x55, "Error in the 1st byte of the bitmap for the fourth Per AID TID Info subfield");
1238 NS_TEST_EXPECT_MSG_EQ (bitmap4[1], 0xaa, "Error in the 2nd byte of the bitmap for the fourth Per AID TID Info subfield");
1239 NS_TEST_EXPECT_MSG_EQ (bitmap4[2], 0x00, "Error in the 3rd byte of the bitmap for the fourth Per AID TID Info subfield");
1240 NS_TEST_EXPECT_MSG_EQ (bitmap4[3], 0xff, "Error in the 4th byte of the bitmap for the fourth Per AID TID Info subfield");
1241 NS_TEST_EXPECT_MSG_EQ (bitmap4[4], 0x0f, "Error in the 5th byte of the bitmap for the fourth Per AID TID Info subfield");
1242 NS_TEST_EXPECT_MSG_EQ (bitmap4[5], 0xf0, "Error in the 6th byte of the bitmap for the fourth Per AID TID Info subfield");
1243 NS_TEST_EXPECT_MSG_EQ (bitmap4[6], 0x00, "Error in the 7th byte of the bitmap for the fourth Per AID TID Info subfield");
1244 NS_TEST_EXPECT_MSG_EQ (bitmap4[7], 0xff, "Error in the 8th byte of the bitmap for the fourth Per AID TID Info subfield");
1245 NS_TEST_EXPECT_MSG_EQ (bitmap4[8], 0x00, "Error in the 9th byte of the bitmap for the fourth Per AID TID Info subfield");
1246 NS_TEST_EXPECT_MSG_EQ (bitmap4[9], 0xff, "Error in the 10th byte of the bitmap for the fourth Per AID TID Info subfield");
1247 NS_TEST_EXPECT_MSG_EQ (bitmap4[10], 0x00, "Error in the 11th byte of the bitmap for the fourth Per AID TID Info subfield");
1248 NS_TEST_EXPECT_MSG_EQ (bitmap4[11], 0xff, "Error in the 12th byte of the bitmap for the fourth Per AID TID Info subfield");
1249 NS_TEST_EXPECT_MSG_EQ (bitmap4[12], 0x00, "Error in the 13th byte of the bitmap for the fourth Per AID TID Info subfield");
1250 NS_TEST_EXPECT_MSG_EQ (bitmap4[13], 0xff, "Error in the 14th byte of the bitmap for the fourth Per AID TID Info subfield");
1251 NS_TEST_EXPECT_MSG_EQ (bitmap4[14], 0x00, "Error in the 15th byte of the bitmap for the fourth Per AID TID Info subfield");
1252 NS_TEST_EXPECT_MSG_EQ (bitmap4[15], 0xff, "Error in the 16th byte of the bitmap for the fourth Per AID TID Info subfield");
1253
1254 /* Check 5th Per AID TID Info subfield */
1255 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAid11 (4), aid5, "Different AID for the fifth Per AID TID Info subfield");
1256 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAckType (4), ackType5, "Different Ack Type for the fifth Per AID TID Info subfield");
1257 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetTidInfo (4), tid5, "Different TID for the fifth Per AID TID Info subfield");
1258 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetStartingSequence (4), startSeq5, "Different starting sequence number for the fifth Per AID TID Info subfield");
1259
1260 auto& bitmap5 = blockAckCopy.GetBitmap (4);
1261 NS_TEST_EXPECT_MSG_EQ (bitmap5.size (), 32, "Different bitmap length for the fifth Per AID TID Info subfield");
1262 NS_TEST_EXPECT_MSG_EQ (bitmap5[0], 0x55, "Error in the 1st byte of the bitmap for the fifth Per AID TID Info subfield");
1263 NS_TEST_EXPECT_MSG_EQ (bitmap5[1], 0xaa, "Error in the 2nd byte of the bitmap for the fifth Per AID TID Info subfield");
1264 NS_TEST_EXPECT_MSG_EQ (bitmap5[2], 0x00, "Error in the 3rd byte of the bitmap for the fifth Per AID TID Info subfield");
1265 NS_TEST_EXPECT_MSG_EQ (bitmap5[3], 0xff, "Error in the 4th byte of the bitmap for the fifth Per AID TID Info subfield");
1266 NS_TEST_EXPECT_MSG_EQ (bitmap5[4], 0x0f, "Error in the 5th byte of the bitmap for the fifth Per AID TID Info subfield");
1267 NS_TEST_EXPECT_MSG_EQ (bitmap5[5], 0xf0, "Error in the 6th byte of the bitmap for the fifth Per AID TID Info subfield");
1268 NS_TEST_EXPECT_MSG_EQ (bitmap5[6], 0x00, "Error in the 7th byte of the bitmap for the fifth Per AID TID Info subfield");
1269 NS_TEST_EXPECT_MSG_EQ (bitmap5[7], 0xff, "Error in the 8th byte of the bitmap for the fifth Per AID TID Info subfield");
1270 NS_TEST_EXPECT_MSG_EQ (bitmap5[8], 0x00, "Error in the 9th byte of the bitmap for the fifth Per AID TID Info subfield");
1271 NS_TEST_EXPECT_MSG_EQ (bitmap5[9], 0xff, "Error in the 10th byte of the bitmap for the fifth Per AID TID Info subfield");
1272 NS_TEST_EXPECT_MSG_EQ (bitmap5[10], 0x00, "Error in the 11th byte of the bitmap for the fifth Per AID TID Info subfield");
1273 NS_TEST_EXPECT_MSG_EQ (bitmap5[11], 0xff, "Error in the 12th byte of the bitmap for the fifth Per AID TID Info subfield");
1274 NS_TEST_EXPECT_MSG_EQ (bitmap5[12], 0x00, "Error in the 13th byte of the bitmap for the fifth Per AID TID Info subfield");
1275 NS_TEST_EXPECT_MSG_EQ (bitmap5[13], 0xff, "Error in the 14th byte of the bitmap for the fifth Per AID TID Info subfield");
1276 NS_TEST_EXPECT_MSG_EQ (bitmap5[14], 0x00, "Error in the 15th byte of the bitmap for the fifth Per AID TID Info subfield");
1277 NS_TEST_EXPECT_MSG_EQ (bitmap5[15], 0xff, "Error in the 16th byte of the bitmap for the fifth Per AID TID Info subfield");
1278 NS_TEST_EXPECT_MSG_EQ (bitmap5[16], 0x00, "Error in the 17th byte of the bitmap for the fifth Per AID TID Info subfield");
1279 NS_TEST_EXPECT_MSG_EQ (bitmap5[17], 0xff, "Error in the 18th byte of the bitmap for the fifth Per AID TID Info subfield");
1280 NS_TEST_EXPECT_MSG_EQ (bitmap5[18], 0x00, "Error in the 19th byte of the bitmap for the fifth Per AID TID Info subfield");
1281 NS_TEST_EXPECT_MSG_EQ (bitmap5[19], 0xff, "Error in the 20th byte of the bitmap for the fifth Per AID TID Info subfield");
1282 NS_TEST_EXPECT_MSG_EQ (bitmap5[20], 0x00, "Error in the 21th byte of the bitmap for the fifth Per AID TID Info subfield");
1283 NS_TEST_EXPECT_MSG_EQ (bitmap5[21], 0xff, "Error in the 22th byte of the bitmap for the fifth Per AID TID Info subfield");
1284 NS_TEST_EXPECT_MSG_EQ (bitmap5[22], 0x00, "Error in the 23th byte of the bitmap for the fifth Per AID TID Info subfield");
1285 NS_TEST_EXPECT_MSG_EQ (bitmap5[23], 0xff, "Error in the 24th byte of the bitmap for the fifth Per AID TID Info subfield");
1286 NS_TEST_EXPECT_MSG_EQ (bitmap5[24], 0x00, "Error in the 25th byte of the bitmap for the fifth Per AID TID Info subfield");
1287 NS_TEST_EXPECT_MSG_EQ (bitmap5[25], 0xff, "Error in the 26th byte of the bitmap for the fifth Per AID TID Info subfield");
1288 NS_TEST_EXPECT_MSG_EQ (bitmap5[26], 0x00, "Error in the 27th byte of the bitmap for the fifth Per AID TID Info subfield");
1289 NS_TEST_EXPECT_MSG_EQ (bitmap5[27], 0xff, "Error in the 28th byte of the bitmap for the fifth Per AID TID Info subfield");
1290 NS_TEST_EXPECT_MSG_EQ (bitmap5[28], 0x00, "Error in the 29th byte of the bitmap for the fifth Per AID TID Info subfield");
1291 NS_TEST_EXPECT_MSG_EQ (bitmap5[29], 0xff, "Error in the 30th byte of the bitmap for the fifth Per AID TID Info subfield");
1292 NS_TEST_EXPECT_MSG_EQ (bitmap5[30], 0x00, "Error in the 31th byte of the bitmap for the fifth Per AID TID Info subfield");
1293 NS_TEST_EXPECT_MSG_EQ (bitmap5[31], 0xff, "Error in the 32th byte of the bitmap for the fifth Per AID TID Info subfield");
1294
1295 /* Check 6th Per AID TID Info subfield */
1296 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAid11 (5), aid6, "Different AID for the sixth Per AID TID Info subfield");
1297 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetAckType (5), ackType6, "Different Ack Type for the sixth Per AID TID Info subfield");
1298 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetTidInfo (5), tid6, "Different TID for the sixth Per AID TID Info subfield");
1299 NS_TEST_EXPECT_MSG_EQ (blockAckCopy.GetUnassociatedStaAddress (5), address6, "Different starting sequence number for the sixth Per AID TID Info subfield");
1300}
1301
1302
1348{
1353 {
1360 void Trace (Time startTime, Time duration, uint8_t linkId);
1362 };
1363
1364public:
1371
1372 void DoRun (void) override;
1373
1374
1375private:
1376 bool m_txop;
1378 uint16_t m_txTotal;
1379 uint16_t m_txSinceBar;
1381 uint16_t m_nBar;
1382 uint16_t m_nBa;
1383
1390 void L7Receive (std::string context, Ptr<const Packet> p, const Address &adr);
1397 void Transmit (std::string context, Ptr<const Packet> p, double power);
1404 void Receive (std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1405};
1406
1407void
1409 uint8_t linkId)
1410{
1411 if (duration > m_max)
1412 {
1413 m_max = duration;
1414 }
1415}
1416
1418 : TestCase ("Test case for Block Ack Policy with aggregation disabled"),
1419 m_txop (txop),
1420 m_received (0),
1421 m_txTotal (0),
1422 m_txSinceBar (0),
1423 m_nBar (0),
1424 m_nBa (0)
1425{
1426}
1427
1429{
1430}
1431
1432void
1434{
1435 if (p->GetSize () == 1400)
1436 {
1437 m_received++;
1438 }
1439}
1440
1441void
1443{
1444 WifiMacHeader hdr;
1445 p->PeekHeader (hdr);
1446
1447 if (m_nBar < 2 && (m_txSinceBar == 9 || m_txTotal == 14))
1448 {
1449 NS_TEST_ASSERT_MSG_EQ (hdr.IsBlockAckReq (), true, "Didn't get a BlockAckReq when expected");
1450 }
1451 else
1452 {
1453 NS_TEST_ASSERT_MSG_EQ (hdr.IsBlockAckReq (), false, "Got a BlockAckReq when not expected");
1454 }
1455
1456 if (hdr.IsQosData ())
1457 {
1458 m_txTotal++;
1459 if (hdr.IsQosBlockAck ())
1460 {
1461 m_txSinceBar++;
1462 }
1463
1464 if (!m_txop)
1465 {
1466 NS_TEST_EXPECT_MSG_EQ ((m_txTotal == 1 || hdr.IsQosBlockAck ()), true, "Unexpected QoS ack policy");
1467 }
1468 else
1469 {
1470 NS_TEST_EXPECT_MSG_EQ ((m_txTotal <= 2 || hdr.IsQosBlockAck ()), true, "Unexpected QoS ack policy");
1471 }
1472 }
1473 else if (hdr.IsBlockAckReq ())
1474 {
1475 m_txSinceBar = 0;
1476 m_nBar++;
1477 }
1478}
1479
1480void
1482{
1483 WifiMacHeader hdr;
1484 p->PeekHeader (hdr);
1485
1486 if (hdr.IsBlockAck ())
1487 {
1488 m_nBa++;
1489 }
1490}
1491
1492void
1494{
1495 NodeContainer wifiStaNode;
1496 wifiStaNode.Create (1);
1497
1499 wifiApNode.Create (1);
1500
1501 YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
1503 phy.SetChannel (channel.Create ());
1504
1506 wifi.SetStandard (WIFI_STANDARD_80211n);
1507 Config::SetDefault ("ns3::WifiDefaultAckManager::BaThreshold", DoubleValue (0.125));
1508 wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
1509
1511 Ssid ssid = Ssid ("ns-3-ssid");
1512 mac.SetType ("ns3::StaWifiMac",
1513 "BE_MaxAmsduSize", UintegerValue (0),
1514 "BE_MaxAmpduSize", UintegerValue (0),
1515 "Ssid", SsidValue (ssid),
1516 /* setting blockack threshold for sta's BE queue */
1517 "BE_BlockAckThreshold", UintegerValue (2),
1518 "ActiveProbing", BooleanValue (false));
1519
1521 staDevices = wifi.Install (phy, mac, wifiStaNode);
1522
1523 mac.SetType ("ns3::ApWifiMac",
1524 "BE_MaxAmsduSize", UintegerValue (0),
1525 "BE_MaxAmpduSize", UintegerValue (0),
1526 "Ssid", SsidValue (ssid),
1527 "BeaconGeneration", BooleanValue (true));
1528
1530 apDevices = wifi.Install (phy, mac, wifiApNode);
1531
1533 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1534
1535 positionAlloc->Add (Vector (0.0, 0.0, 0.0));
1536 positionAlloc->Add (Vector (1.0, 0.0, 0.0));
1537 mobility.SetPositionAllocator (positionAlloc);
1538
1539 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1540 mobility.Install (wifiApNode);
1541 mobility.Install (wifiStaNode);
1542
1543 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice> (apDevices.Get (0));
1544 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice> (staDevices.Get (0));
1545
1546 // Disable A-MPDU aggregation
1547 sta_device->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0));
1548 TxopDurationTracer txopTracer;
1549
1550 if (m_txop)
1551 {
1552 PointerValue ptr;
1553 sta_device->GetMac ()->GetAttribute ("BE_Txop", ptr);
1554 ptr.Get<QosTxop> ()->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &txopTracer));
1555
1556 // set the TXOP limit on BE AC
1557 ap_device->GetMac ()->GetAttribute ("BE_Txop", ptr);
1558 ptr.Get<QosTxop> ()->SetTxopLimit (MicroSeconds (4800));
1559 }
1560
1561 PacketSocketAddress socket;
1562 socket.SetSingleDevice (sta_device->GetIfIndex ());
1563 socket.SetPhysicalAddress (ap_device->GetAddress ());
1564 socket.SetProtocol (1);
1565
1566 // give packet socket powers to nodes.
1567 PacketSocketHelper packetSocket;
1568 packetSocket.Install (wifiStaNode);
1569 packetSocket.Install (wifiApNode);
1570
1571 // the first client application generates a single packet, which is sent
1572 // with the normal ack policy because there are no other packets queued
1573 Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient> ();
1574 client1->SetAttribute ("PacketSize", UintegerValue (1400));
1575 client1->SetAttribute ("MaxPackets", UintegerValue (1));
1576 client1->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1577 client1->SetRemote (socket);
1578 wifiStaNode.Get (0)->AddApplication (client1);
1579 client1->SetStartTime (Seconds (1));
1580 client1->SetStopTime (Seconds (3.0));
1581
1582 // the second client application generates 13 packets. Even if when the first
1583 // packet is queued the queue is empty, the first packet is not transmitted
1584 // immediately, but the EDCAF waits for the next slot boundary. At that time,
1585 // other packets have been queued, hence a BA agreement is established first.
1586 Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient> ();
1587 client2->SetAttribute ("PacketSize", UintegerValue (1400));
1588 client2->SetAttribute ("MaxPackets", UintegerValue (13));
1589 client2->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1590 client2->SetRemote (socket);
1591 wifiStaNode.Get (0)->AddApplication (client2);
1592 client2->SetStartTime (Seconds (1.5));
1593 client2->SetStopTime (Seconds (3.0));
1594
1595 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
1596 server->SetLocal (socket);
1597 wifiApNode.Get (0)->AddApplication (server);
1598 server->SetStartTime (Seconds (0.0));
1599 server->SetStopTime (Seconds (4.0));
1600
1601 Config::Connect ("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx", MakeCallback (&BlockAckAggregationDisabledTest::L7Receive, this));
1602 Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyTxBegin", MakeCallback (&BlockAckAggregationDisabledTest::Transmit, this));
1603 Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyRxBegin", MakeCallback (&BlockAckAggregationDisabledTest::Receive, this));
1604
1605 Simulator::Stop (Seconds (5));
1606 Simulator::Run ();
1607
1608 Simulator::Destroy ();
1609
1610 // The client applications generate 14 packets, so we expect that the wifi PHY
1611 // layer transmits 14 MPDUs, the server application receives 14 packets, and
1612 // two BARs are transmitted.
1613 NS_TEST_EXPECT_MSG_EQ (m_txTotal, 14, "Unexpected number of transmitted packets");
1614 NS_TEST_EXPECT_MSG_EQ (m_received, 14, "Unexpected number of received packets");
1615 NS_TEST_EXPECT_MSG_EQ (m_nBar, 2, "Unexpected number of Block Ack Requests");
1616 NS_TEST_EXPECT_MSG_EQ (m_nBa, 2, "Unexpected number of Block Ack Responses");
1617 if (m_txop)
1618 {
1619 NS_TEST_EXPECT_MSG_LT (txopTracer.m_max, MicroSeconds (4800), "TXOP duration exceeded!");
1620 NS_TEST_EXPECT_MSG_GT (txopTracer.m_max, MicroSeconds (3008), "The maximum TXOP duration is too short!");
1621 }
1622}
1623
1631{
1632public:
1634};
1635
1637 : TestSuite ("wifi-block-ack", UNIT)
1638{
1639 AddTestCase (new PacketBufferingCaseA, TestCase::QUICK);
1640 AddTestCase (new PacketBufferingCaseB, TestCase::QUICK);
1641 AddTestCase (new OriginatorBlockAckWindowTest, TestCase::QUICK);
1642 AddTestCase (new CtrlBAckResponseHeaderTest, TestCase::QUICK);
1643 AddTestCase (new BlockAckRecipientBufferTest (0), TestCase::QUICK);
1644 AddTestCase (new BlockAckRecipientBufferTest (4090), TestCase::QUICK);
1645 AddTestCase (new MultiStaCtrlBAckResponseHeaderTest, TestCase::QUICK);
1646 AddTestCase (new BlockAckAggregationDisabledTest (false), TestCase::QUICK);
1647 AddTestCase (new BlockAckAggregationDisabledTest (true), TestCase::QUICK);
1648}
1649
void Run(ObjectFactory &factory, uint32_t pop, uint32_t total, uint32_t runs, Ptr< RandomVariableStream > eventStream, bool calRev)
Perform the runs for a single scheduler type.
static BlockAckTestSuite g_blockAckTestSuite
the test suite
Test for Block Ack Policy with aggregation disabled.
uint16_t m_nBa
received BlockAck frames
void DoRun(void) override
Implementation to actually run this TestCase.
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
bool m_txop
true for non-null TXOP limit
Test for recipient reordering buffer operations.
void DoRun(void) override
Implementation to actually run this TestCase.
uint16_t m_ssn
the Starting Sequence Number used to initialize WinStartB
void ForwardUp(Ptr< WifiMacQueueItem > mpdu, uint8_t linkId)
Keep track of MPDUs received on the given link that are forwarded up.
BlockAckRecipientBufferTest(uint16_t ssn)
Constructor.
std::list< Ptr< WifiMacQueueItem > > m_fwup
list of MPDUs that have been forwarded up
Block Ack Test Suite.
Test for block ack header.
CtrlBAckResponseHeader m_blockAckHdr
block ack header
void DoRun(void) override
Implementation to actually run this TestCase.
Test for Multi-STA block ack header.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test for the originator block ack window.
void DoRun(void) override
Implementation to actually run this TestCase.
Packet Buffering Case A.
void DoRun(void) override
Implementation to actually run this TestCase.
std::list< uint16_t > m_expectedBuffer
expected test buffer
Packet Buffering Case B.
std::list< uint16_t > m_expectedBuffer
expected test buffer
void DoRun(void) override
Implementation to actually run this TestCase.
a polymophic address class
Definition: address.h:91
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
std::size_t GetWinSize(void) const
Get the window size.
uint16_t GetWinStart(void) const
Get the current winStart 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.
uint16_t GetWinEnd(void) const
Get the current winEnd value.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Headers for BlockAck response.
Definition: ctrl-headers.h:202
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(void) 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:41
an EUI-48 address
Definition: mac48-address.h:44
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:159
Maintains the state and information about transmitted MPDUs with Ack Policy set to Block Ack for an o...
void InitTxWindow(void)
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
void NotifyAckedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that the given MPDU has been acknowledged and advance the transmit window if possible.
void NotifyTransmittedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Advance the transmit window so as to include the transmitted MPDU, if the latter is not an old packet...
BlockAckWindow m_txWindow
originator's transmit window
uint16_t GetStartingSequence(void) const override
Return the starting sequence number of the transmit window, if a transmit window has been initialized...
void NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Advance the transmit window beyond the MPDU that has been reported to be discarded.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get(void) const
Definition: pointer.h:201
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:72
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< WifiMacQueueItem > 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.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
AttributeValue implementation for Time.
Definition: nstime.h:1309
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:322
Implements the IEEE 802.11 MAC header.
bool IsBlockAck(void) const
Return true if the header is a BlockAck header.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
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.
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 IsBlockAckReq(void) const
Return true if the header is a BlockAckRequest header.
bool IsQosBlockAck(void) const
Return if the QoS Ack policy is Block Ack.
create MAC layers for a ns3::WifiNetDevice.
Ptr< WifiMac > GetMac(void) const
Address GetAddress(void) const override
uint32_t GetIfIndex(void) const override
manage and create wifi channel objects for the YANS model.
Make it easy to create and manage PHY objects for the YANS model.
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:141
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:748
#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:899
#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:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1261
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
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:167
@ WIFI_STANDARD_80211n
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
Definition: wifi-utils.h:131
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
staDevices
Definition: third.py:93
ssid
Definition: third.py:88
channel
Definition: third.py:83
mac
Definition: third.py:87
wifi
Definition: third.py:90
apDevices
Definition: third.py:96
wifiApNode
Definition: third.py:81
mobility
Definition: third.py:98
phy
Definition: third.py:84
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.
enum Variant m_variant
Block Ack variant.
std::vector< uint8_t > m_bitmapLen
Length (bytes) of included bitmaps.