A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
block-ack-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, 2010 MIRKO BANCHI
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mirko Banchi <mk.banchi@gmail.com>
18  */
19 
20 #include "ns3/ap-wifi-mac.h"
21 #include "ns3/boolean.h"
22 #include "ns3/config.h"
23 #include "ns3/ctrl-headers.h"
24 #include "ns3/double.h"
25 #include "ns3/mac-rx-middle.h"
26 #include "ns3/mobility-helper.h"
27 #include "ns3/originator-block-ack-agreement.h"
28 #include "ns3/packet-socket-client.h"
29 #include "ns3/packet-socket-helper.h"
30 #include "ns3/packet-socket-server.h"
31 #include "ns3/packet.h"
32 #include "ns3/pointer.h"
33 #include "ns3/qos-txop.h"
34 #include "ns3/qos-utils.h"
35 #include "ns3/recipient-block-ack-agreement.h"
36 #include "ns3/string.h"
37 #include "ns3/test.h"
38 #include "ns3/wifi-mac-header.h"
39 #include "ns3/wifi-mpdu.h"
40 #include "ns3/wifi-net-device.h"
41 #include "ns3/yans-wifi-helper.h"
42 
43 #include <list>
44 
45 using 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 {
86  public:
88  ~PacketBufferingCaseA() override;
89 
90  private:
91  void DoRun() override;
92  std::list<uint16_t> m_expectedBuffer;
93 };
94 
96  : TestCase("Check correct order of buffering when startSequence < endSeq")
97 {
98  m_expectedBuffer.push_back(64016);
99  m_expectedBuffer.push_back(0);
100  m_expectedBuffer.push_back(16);
101  m_expectedBuffer.push_back(56000);
102  m_expectedBuffer.push_back(63984);
103 }
104 
106 {
107 }
108 
109 void
111 {
112  std::list<uint16_t> m_buffer;
113  std::list<uint16_t>::iterator i;
114  std::list<uint16_t>::iterator j;
115  m_buffer.push_back(0);
116  m_buffer.push_back(16);
117  m_buffer.push_back(56000);
118 
119  uint16_t endSeq = 4000;
120 
121  uint16_t receivedSeq = 4001 * 16;
122  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
123  /* cycle to right position for this packet */
124  for (i = m_buffer.begin(); i != m_buffer.end(); i++)
125  {
126  if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
127  {
128  // position found
129  break;
130  }
131  }
132  m_buffer.insert(i, receivedSeq);
133 
134  receivedSeq = 3999 * 16;
135  mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
136  /* cycle to right position for this packet */
137  for (i = m_buffer.begin(); i != m_buffer.end(); i++)
138  {
139  if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
140  {
141  // position found
142  break;
143  }
144  }
145  m_buffer.insert(i, receivedSeq);
146 
147  for (i = m_buffer.begin(), j = m_expectedBuffer.begin(); i != m_buffer.end(); i++, j++)
148  {
149  NS_TEST_EXPECT_MSG_EQ(*i, *j, "error in buffer order");
150  }
151 }
152 
183 {
184  public:
186  ~PacketBufferingCaseB() override;
187 
188  private:
189  void DoRun() override;
190  std::list<uint16_t> m_expectedBuffer;
191 };
192 
194  : TestCase("Check correct order of buffering when startSequence > endSeq")
195 {
196  m_expectedBuffer.push_back(240);
197  m_expectedBuffer.push_back(241);
198  m_expectedBuffer.push_back(256);
199  m_expectedBuffer.push_back(64000);
200  m_expectedBuffer.push_back(64800);
201  m_expectedBuffer.push_back(16);
202 }
203 
205 {
206 }
207 
208 void
210 {
211  std::list<uint16_t> m_buffer;
212  std::list<uint16_t>::iterator i;
213  std::list<uint16_t>::iterator j;
214  m_buffer.push_back(256);
215  m_buffer.push_back(64000);
216  m_buffer.push_back(16);
217 
218  uint16_t endSeq = 10;
219 
220  uint16_t receivedSeq = 15 * 16;
221  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
222  /* cycle to right position for this packet */
223  for (i = m_buffer.begin(); i != m_buffer.end(); i++)
224  {
225  if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
226  {
227  // position found
228  break;
229  }
230  }
231  m_buffer.insert(i, receivedSeq);
232 
233  receivedSeq = 15 * 16 + 1;
234  mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
235  /* cycle to right position for this packet */
236  for (i = m_buffer.begin(); i != m_buffer.end(); i++)
237  {
238  if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
239  {
240  // position found
241  break;
242  }
243  }
244  m_buffer.insert(i, receivedSeq);
245 
246  receivedSeq = 4050 * 16;
247  mappedSeq = QosUtilsMapSeqControlToUniqueInteger(receivedSeq, endSeq);
248  /* cycle to right position for this packet */
249  for (i = m_buffer.begin(); i != m_buffer.end(); i++)
250  {
251  if (QosUtilsMapSeqControlToUniqueInteger((*i), endSeq) >= mappedSeq)
252  {
253  // position found
254  break;
255  }
256  }
257  m_buffer.insert(i, receivedSeq);
258 
259  for (i = m_buffer.begin(), j = m_expectedBuffer.begin(); i != m_buffer.end(); i++, j++)
260  {
261  NS_TEST_EXPECT_MSG_EQ(*i, *j, "error in buffer order");
262  }
263 }
264 
272 {
273  public:
275 
276  private:
277  void DoRun() override;
278 };
279 
281  : TestCase("Check the correctness of the originator block ack window")
282 {
283 }
284 
285 void
287 {
288  uint16_t winSize = 16;
289  uint16_t startingSeq = 4090;
290 
291  OriginatorBlockAckAgreement agreement(Mac48Address("00:00:00:00:00:01"), 0);
292  agreement.SetBufferSize(winSize);
293  agreement.SetStartingSequence(startingSeq);
294  agreement.InitTxWindow();
295 
296  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.GetWinSize(), winSize, "Incorrect window size");
297  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.GetWinStart(), startingSeq, "Incorrect winStart");
298  // check that all the elements in the window are cleared
299  for (uint16_t i = 0; i < winSize; i++)
300  {
301  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
302  false,
303  "Not all flags are cleared after initialization");
304  }
305 
306  // Notify the acknowledgment of 5 packets
307  WifiMacHeader hdr;
309  Ptr<WifiMpdu> mpdu = Create<WifiMpdu>(Create<Packet>(), hdr);
310  uint16_t seqNumber = startingSeq;
311  mpdu->GetHeader().SetSequenceNumber(seqNumber);
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  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
321  agreement.NotifyAckedMpdu(mpdu);
322 
323  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
324  agreement.NotifyAckedMpdu(mpdu);
325 
326  // the current window must look like this:
327  //
328  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
329  // ^
330  // |
331  // HEAD
332 
333  startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
335  startingSeq,
336  "Incorrect starting sequence after 5 acknowledgments");
337  for (uint16_t i = 0; i < winSize; i++)
338  {
339  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
340  false,
341  "Not all flags are cleared after 5 acknowledgments");
342  }
343 
344  // the next MPDU is not acknowledged, hence the window is blocked while the
345  // subsequent 4 MPDUs are acknowledged
346  ++seqNumber %= SEQNO_SPACE_SIZE;
347  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
348  agreement.NotifyAckedMpdu(mpdu);
349 
350  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
351  agreement.NotifyAckedMpdu(mpdu);
352 
353  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
354  agreement.NotifyAckedMpdu(mpdu);
355 
356  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
357  agreement.NotifyAckedMpdu(mpdu);
358 
359  // the current window must look like this:
360  //
361  // |0|0|0|0|0|0|1|1|1|1|0|0|0|0|0|0|
362  // ^
363  // |
364  // HEAD
365 
367  startingSeq,
368  "Incorrect starting sequence after 1 unacknowledged MPDU");
369  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(0),
370  false,
371  "Incorrect flag after 1 unacknowledged MPDU");
372  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(1),
373  true,
374  "Incorrect flag after 1 unacknowledged MPDU");
375  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(2),
376  true,
377  "Incorrect flag after 1 unacknowledged MPDU");
378  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(3),
379  true,
380  "Incorrect flag after 1 unacknowledged MPDU");
381  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(4),
382  true,
383  "Incorrect flag after 1 unacknowledged MPDU");
384  for (uint16_t i = 5; i < winSize; i++)
385  {
386  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
387  false,
388  "Incorrect flag after 1 unacknowledged MPDU");
389  }
390 
391  // the missing MPDU is now acknowledged; the window moves forward and the starting
392  // sequence number is the one of the first unacknowledged MPDU
393  mpdu->GetHeader().SetSequenceNumber(startingSeq);
394  agreement.NotifyAckedMpdu(mpdu);
395 
396  // the current window must look like this:
397  //
398  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
399  // ^
400  // |
401  // HEAD
402 
403  startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
405  startingSeq,
406  "Incorrect starting sequence after acknowledgment of missing MPDU");
407  for (uint16_t i = 0; i < winSize; i++)
408  {
409  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
410  false,
411  "Not all flags are cleared after acknowledgment of missing MPDU");
412  }
413 
414  // Now, create a hole of 3 MPDUs before 4 acknowledged MPDUs, another hole of 2 MPDUs before 3
415  // acknowledged MPDUs
416  seqNumber = (seqNumber + 4) % SEQNO_SPACE_SIZE;
417  mpdu->GetHeader().SetSequenceNumber(seqNumber);
418  agreement.NotifyAckedMpdu(mpdu);
419 
420  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
421  agreement.NotifyAckedMpdu(mpdu);
422 
423  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
424  agreement.NotifyAckedMpdu(mpdu);
425 
426  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
427  agreement.NotifyAckedMpdu(mpdu);
428 
429  seqNumber = (seqNumber + 3) % SEQNO_SPACE_SIZE;
430  mpdu->GetHeader().SetSequenceNumber(seqNumber);
431  agreement.NotifyAckedMpdu(mpdu);
432 
433  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
434  agreement.NotifyAckedMpdu(mpdu);
435 
436  mpdu->GetHeader().SetSequenceNumber(++seqNumber %= SEQNO_SPACE_SIZE);
437  agreement.NotifyAckedMpdu(mpdu);
438 
439  // the current window must look like this:
440  //
441  // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
442  // ^
443  // |
444  // HEAD
445 
447  startingSeq,
448  "Incorrect starting sequence after 3 unacknowledged MPDUs");
449  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(0),
450  false,
451  "Incorrect flag after 3 unacknowledged MPDUs");
452  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(1),
453  false,
454  "Incorrect flag after 3 unacknowledged MPDUs");
455  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(2),
456  false,
457  "Incorrect flag after 3 unacknowledged MPDUs");
458  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(3),
459  true,
460  "Incorrect flag after 3 unacknowledged MPDUs");
461  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(4),
462  true,
463  "Incorrect flag after 3 unacknowledged MPDUs");
464  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(5),
465  true,
466  "Incorrect flag after 3 unacknowledged MPDUs");
467  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(6),
468  true,
469  "Incorrect flag after 3 unacknowledged MPDUs");
470  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(7),
471  false,
472  "Incorrect flag after 3 unacknowledged MPDUs");
473  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(8),
474  false,
475  "Incorrect flag after 3 unacknowledged MPDUs");
476  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(9),
477  true,
478  "Incorrect flag after 3 unacknowledged MPDUs");
479  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(10),
480  true,
481  "Incorrect flag after 3 unacknowledged MPDUs");
482  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(11),
483  true,
484  "Incorrect flag after 3 unacknowledged MPDUs");
485  for (uint16_t i = 12; i < winSize; i++)
486  {
487  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
488  false,
489  "Incorrect flag after 3 unacknowledged MPDUs");
490  }
491 
492  // the transmission of an MPDU beyond the current window (by 2 positions) is
493  // notified, hence the window moves forward 2 positions
494  seqNumber = (agreement.m_txWindow.GetWinEnd() + 2) % SEQNO_SPACE_SIZE;
495  mpdu->GetHeader().SetSequenceNumber(seqNumber);
496  agreement.NotifyTransmittedMpdu(mpdu);
497 
498  // the current window must look like this:
499  //
500  // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
501  // ^
502  // |
503  // HEAD
504 
505  startingSeq = (startingSeq + 2) % SEQNO_SPACE_SIZE;
507  agreement.GetStartingSequence(),
508  startingSeq,
509  "Incorrect starting sequence after transmitting an MPDU beyond the current window");
510  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(0),
511  false,
512  "Incorrect flag after transmitting an MPDU beyond the current window");
513  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(1),
514  true,
515  "Incorrect flag after transmitting an MPDU beyond the current window");
516  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(2),
517  true,
518  "Incorrect flag after transmitting an MPDU beyond the current window");
519  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(3),
520  true,
521  "Incorrect flag after transmitting an MPDU beyond the current window");
522  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(4),
523  true,
524  "Incorrect flag after transmitting an MPDU beyond the current window");
525  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(5),
526  false,
527  "Incorrect flag after transmitting an MPDU beyond the current window");
528  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(6),
529  false,
530  "Incorrect flag after transmitting an MPDU beyond the current window");
531  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(7),
532  true,
533  "Incorrect flag after transmitting an MPDU beyond the current window");
534  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(8),
535  true,
536  "Incorrect flag after transmitting an MPDU beyond the current window");
537  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(9),
538  true,
539  "Incorrect flag after transmitting an MPDU beyond the current window");
540  for (uint16_t i = 10; i < winSize; i++)
541  {
543  agreement.m_txWindow.At(i),
544  false,
545  "Incorrect flag after transmitting an MPDU beyond the current window");
546  }
547 
548  // another MPDU is transmitted beyond the current window. Now, the window advances
549  // until the first unacknowledged MPDU
550  seqNumber = (agreement.m_txWindow.GetWinEnd() + 1) % SEQNO_SPACE_SIZE;
551  mpdu->GetHeader().SetSequenceNumber(seqNumber);
552  agreement.NotifyTransmittedMpdu(mpdu);
553 
554  // the current window must look like this:
555  //
556  // |0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|
557  // ^
558  // |
559  // HEAD
560 
561  startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
563  agreement.GetStartingSequence(),
564  startingSeq,
565  "Incorrect starting sequence after transmitting another MPDU beyond the current window");
567  agreement.m_txWindow.At(0),
568  false,
569  "Incorrect flag after transmitting another MPDU beyond the current window");
571  agreement.m_txWindow.At(1),
572  false,
573  "Incorrect flag after transmitting another MPDU beyond the current window");
575  agreement.m_txWindow.At(2),
576  true,
577  "Incorrect flag after transmitting another MPDU beyond the current window");
579  agreement.m_txWindow.At(3),
580  true,
581  "Incorrect flag after transmitting another MPDU beyond the current window");
583  agreement.m_txWindow.At(4),
584  true,
585  "Incorrect flag after transmitting another MPDU beyond the current window");
586  for (uint16_t i = 5; i < winSize; i++)
587  {
589  agreement.m_txWindow.At(i),
590  false,
591  "Incorrect flag after transmitting another MPDU beyond the current window");
592  }
593 
594  // the MPDU next to winStart is discarded, hence the window advances to make it an old packet.
595  // Since the subsequent MPDUs have been acknowledged, the window advances further.
596  seqNumber = (startingSeq + 1) % SEQNO_SPACE_SIZE;
597  mpdu->GetHeader().SetSequenceNumber(seqNumber);
598  agreement.NotifyDiscardedMpdu(mpdu);
599 
600  // the current window must look like this:
601  //
602  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
603  // ^
604  // |
605  // HEAD
606 
607  startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
609  startingSeq,
610  "Incorrect starting sequence after discarding an MPDU");
611  for (uint16_t i = 0; i < winSize; i++)
612  {
613  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
614  false,
615  "Incorrect flag after discarding an MPDU");
616  }
617 
618  // Finally, check that the window correctly advances when the MPDU with the starting sequence
619  // number is acknowledged after being the only unacknowledged MPDU
620  for (uint16_t i = 1; i < winSize; i++)
621  {
622  mpdu->GetHeader().SetSequenceNumber((startingSeq + i) % SEQNO_SPACE_SIZE);
623  agreement.NotifyAckedMpdu(mpdu);
624  }
625 
626  // the current window must look like this:
627  //
628  // |1|1|1|1|1|1|0|1|1|1|1|1|1|1|1|1|
629  // ^
630  // |
631  // HEAD
632 
634  startingSeq,
635  "Incorrect starting sequence after acknowledging all but the first MPDU");
636  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(0),
637  false,
638  "Incorrect flag after acknowledging all but the first MPDU");
639  for (uint16_t i = 1; i < winSize; i++)
640  {
641  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
642  true,
643  "Incorrect flag after acknowledging all but the first MPDU");
644  }
645 
646  // acknowledge the first MPDU
647  mpdu->GetHeader().SetSequenceNumber(startingSeq % SEQNO_SPACE_SIZE);
648  agreement.NotifyAckedMpdu(mpdu);
649 
650  // the current window must look like this:
651  //
652  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
653  // ^
654  // |
655  // HEAD
656 
657  startingSeq = (startingSeq + winSize) % SEQNO_SPACE_SIZE;
659  startingSeq,
660  "Incorrect starting sequence after acknowledging the first MPDU");
661  for (uint16_t i = 0; i < winSize; i++)
662  {
663  NS_TEST_EXPECT_MSG_EQ(agreement.m_txWindow.At(i),
664  false,
665  "Incorrect flag after acknowledging the first MPDU");
666  }
667 }
668 
676 {
677  public:
679 
680  private:
681  void DoRun() override;
683 };
684 
686  : TestCase("Check the correctness of block ack compressed bitmap")
687 {
688 }
689 
690 void
692 {
693  m_blockAckHdr.SetType(BlockAckType::COMPRESSED);
694 
695  // Case 1: startSeq < endSeq
696  // 179 242
698  for (uint16_t i = 179; i < 220; i++)
699  {
701  }
702  for (uint16_t i = 225; i <= 242; i++)
703  {
705  }
706  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
707  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
708  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0xff, "error in compressed bitmap");
709  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0xff, "error in compressed bitmap");
710  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0xff, "error in compressed bitmap");
711  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0xc1, "error in compressed bitmap");
712  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0xff, "error in compressed bitmap");
713  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0xff, "error in compressed bitmap");
715  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
716  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
717  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0xff, "error in compressed bitmap");
718  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0xff, "error in compressed bitmap");
719  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0xff, "error in compressed bitmap");
720  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0xc1, "error in compressed bitmap");
721  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0xff, "error in compressed bitmap");
722  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0xff, "error in compressed bitmap");
723  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(220), false, "error in compressed bitmap");
724  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(225), true, "error in compressed bitmap");
726  false,
727  "error in compressed bitmap");
728 
730 
731  // Case 2: startSeq > endSeq
732  // 4090 58
734  for (uint16_t i = 4090; i != 10; i = (i + 1) % 4096)
735  {
737  }
738  for (uint16_t i = 22; i < 25; i++)
739  {
741  }
742  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
743  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
744  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0x00, "error in compressed bitmap");
745  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0x70, "error in compressed bitmap");
746  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0x00, "error in compressed bitmap");
747  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0x00, "error in compressed bitmap");
748  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0x00, "error in compressed bitmap");
749  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0x00, "error in compressed bitmap");
751  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[0], 0xff, "error in compressed bitmap");
752  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[1], 0xff, "error in compressed bitmap");
753  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[2], 0x00, "error in compressed bitmap");
754  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[3], 0x70, "error in compressed bitmap");
755  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[4], 0x00, "error in compressed bitmap");
756  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[5], 0x00, "error in compressed bitmap");
757  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[6], 0x00, "error in compressed bitmap");
758  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.GetBitmap()[7], 0x00, "error in compressed bitmap");
759  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(4090), true, "error in compressed bitmap");
760  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(4095), true, "error in compressed bitmap");
761  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(10), false, "error in compressed bitmap");
762  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(35), false, "error in compressed bitmap");
763  NS_TEST_EXPECT_MSG_EQ(m_blockAckHdr.IsPacketReceived(80), false, "error in compressed bitmap");
764 }
765 
773 {
774  public:
779  BlockAckRecipientBufferTest(uint16_t ssn);
780  ~BlockAckRecipientBufferTest() override;
781 
782  void DoRun() override;
783 
790  void ForwardUp(Ptr<const WifiMpdu> mpdu, uint8_t linkId);
791 
792  private:
793  uint16_t m_ssn;
794  std::list<Ptr<const WifiMpdu>> m_fwup;
795 };
796 
798  : TestCase("Test case for Block Ack recipient reordering buffer operations"),
799  m_ssn(ssn)
800 {
801 }
802 
804 {
805 }
806 
807 void
809 {
810  m_fwup.push_back(mpdu);
811 }
812 
813 void
815 {
816  Ptr<MacRxMiddle> rxMiddle = Create<MacRxMiddle>();
817  rxMiddle->SetForwardCallback(MakeCallback(&BlockAckRecipientBufferTest::ForwardUp, this));
818 
819  RecipientBlockAckAgreement agreement(Mac48Address::Allocate() /* originator */,
820  true /* amsduSupported */,
821  0 /* tid */,
822  10 /* bufferSize */,
823  0 /* timeout */,
824  m_ssn,
825  true /* htSupported */);
826  agreement.SetMacRxMiddle(rxMiddle);
827 
828  WifiMacHeader hdr;
830  hdr.SetAddr1(Mac48Address::Allocate());
831  hdr.SetQosTid(0);
832 
833  // Notify the reception of an MPDU with SN = SSN.
835  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
836 
837  // This MPDU is forwarded up and WinStartB is set to SSN + 1.
838  NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 1, "MPDU with SN=SSN must have been forwarded up");
839  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
840  m_ssn,
841  "The MPDU forwarded up is not the expected one");
842 
843  m_fwup.clear();
844 
845  // Notify the reception of MPDUs with SN = SSN + {4, 2, 5, 3, 10, 7}
846  // Recipient buffer: | |X|X|X|X| |X| | |X|
847  // ^
848  // |
849  // SSN + 1
851  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
853  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
855  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
857  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
859  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
861  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
862 
863  // No MPDU is forwarded up because the one with SN = SSN + 1 is missing
864  NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
865 
866  // Notify the reception of an "old" MPDU (SN = SSN)
868  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
869 
870  // No MPDU is forwarded up
871  NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
872 
873  // Notify the reception of a duplicate MPDU (SN = SSN + 2)
875  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(10), hdr));
876 
877  // No MPDU is forwarded up
878  NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
879 
880  // Notify the reception of an MPDU with SN = SSN + 1
881  // Recipient buffer: |X|X|X|X|X| |X| | |X|
882  // ^
883  // |
884  // SSN + 1
886  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
887 
888  // All the MPDUs with SN = SSN + {1, 2, 3, 4, 5} must have been forwarded up in order
889  NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 5, "5 MPDUs must have been forwarded up");
890 
891  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
892  (m_ssn + 1) % SEQNO_SPACE_SIZE,
893  "The MPDU forwarded up is not the expected one");
894  m_fwup.pop_front();
895 
896  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
897  (m_ssn + 2) % SEQNO_SPACE_SIZE,
898  "The MPDU forwarded up is not the expected one");
899  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetPacketSize(),
900  0,
901  "The MPDU forwarded up is not the expected one");
902  m_fwup.pop_front();
903 
904  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
905  (m_ssn + 3) % SEQNO_SPACE_SIZE,
906  "The MPDU forwarded up is not the expected one");
907  m_fwup.pop_front();
908 
909  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
910  (m_ssn + 4) % SEQNO_SPACE_SIZE,
911  "The MPDU forwarded up is not the expected one");
912  m_fwup.pop_front();
913 
914  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
915  (m_ssn + 5) % SEQNO_SPACE_SIZE,
916  "The MPDU forwarded up is not the expected one");
917  m_fwup.pop_front();
918 
919  // Recipient buffer: | |X| | |X| | | | | |
920  // ^ ^
921  // | |
922  // SSN + 6 SSN + 15
923  // Notify the reception of an MPDU beyond the current window (SN = SSN + 17)
925  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
926 
927  // WinStartB is set to SSN + 8 (so that WinEndB = SSN + 17). The MPDU with
928  // SN = SSN + 7 is forwarded up, irrespective of the missed reception of the
929  // MPDU with SN = SSN + 6
930  NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 1, "One MPDU must have been forwarded up");
931 
932  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
933  (m_ssn + 7) % SEQNO_SPACE_SIZE,
934  "The MPDU forwarded up is not the expected one");
935  m_fwup.pop_front();
936 
937  // Recipient buffer: | | |X| | | | | | |X|
938  // ^ ^
939  // | |
940  // SSN + 8 SSN + 17
941  // Notify the reception of a BlockAckReq with SSN = SSN + 7
942  agreement.NotifyReceivedBar((m_ssn + 7) % SEQNO_SPACE_SIZE);
943 
944  // No MPDU is forwarded up
945  NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
946 
947  // Notify the reception of a BlockAckReq with SSN = SSN + 8
948  agreement.NotifyReceivedBar((m_ssn + 8) % SEQNO_SPACE_SIZE);
949 
950  // No MPDU is forwarded up
951  NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
952 
953  // Notify the reception of MPDUs with SN = SSN + {9, 11}
954  // Recipient buffer: | |X|X|X| | | | | |X|
955  // ^ ^
956  // | |
957  // SSN + 8 SSN + 17
959  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
961  agreement.NotifyReceivedMpdu(Create<WifiMpdu>(Create<Packet>(), hdr));
962 
963  // No MPDU is forwarded up because the one with SN = SSN + 8 is missing
964  NS_TEST_ASSERT_MSG_EQ(m_fwup.empty(), true, "No MPDU must have been forwarded up");
965 
966  // Notify the reception of a BlockAckReq with SSN = SSN + 10
967  agreement.NotifyReceivedBar((m_ssn + 10) % SEQNO_SPACE_SIZE);
968 
969  // Forward up buffered MPDUs with SN < SSN + 10 (the MPDU with SN = SSN + 9)
970  // and then buffered MPDUs with SN >= SSN + 10 until a hole is found (MPDUs
971  // with SN = SSN + 10 and SN = SSN + 11)
972  NS_TEST_ASSERT_MSG_EQ(m_fwup.size(), 3, "3 MPDUs must have been forwarded up");
973 
974  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
975  (m_ssn + 9) % SEQNO_SPACE_SIZE,
976  "The MPDU forwarded up is not the expected one");
977  m_fwup.pop_front();
978 
979  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
980  (m_ssn + 10) % SEQNO_SPACE_SIZE,
981  "The MPDU forwarded up is not the expected one");
982  m_fwup.pop_front();
983 
984  NS_TEST_ASSERT_MSG_EQ(m_fwup.front()->GetHeader().GetSequenceNumber(),
985  (m_ssn + 11) % SEQNO_SPACE_SIZE,
986  "The MPDU forwarded up is not the expected one");
987  m_fwup.pop_front();
988 
989  Simulator::Run();
990  Simulator::Destroy();
991 }
992 
1000 {
1001  public:
1003 
1004  private:
1005  void DoRun() override;
1006 };
1007 
1009  : TestCase("Check the correctness of Multi-STA block ack")
1010 {
1011 }
1012 
1013 void
1015 {
1016  // Create a Multi-STA Block Ack with 6 Per AID TID Info subfields
1017  BlockAckType baType(BlockAckType::MULTI_STA, {0, 4, 8, 16, 32, 8});
1018 
1019  CtrlBAckResponseHeader blockAck;
1020  blockAck.SetType(baType);
1021 
1022  /* 1st Per AID TID Info subfield */
1023  uint16_t aid1 = 100;
1024  bool ackType1 = true;
1025  uint8_t tid1 = 1;
1026 
1027  blockAck.SetAid11(aid1, 0);
1028  blockAck.SetAckType(ackType1, 0);
1029  blockAck.SetTidInfo(tid1, 0);
1030 
1031  /* 2nd Per AID TID Info subfield */
1032  uint16_t aid2 = 200;
1033  bool ackType2 = false;
1034  uint8_t tid2 = 2;
1035  uint16_t startSeq2 = 1000;
1036 
1037  blockAck.SetAid11(aid2, 1);
1038  blockAck.SetAckType(ackType2, 1);
1039  blockAck.SetTidInfo(tid2, 1);
1040  blockAck.SetStartingSequence(startSeq2, 1);
1041  // 1st byte of the bitmap: 01010101
1042  for (uint16_t i = startSeq2; i < startSeq2 + 8; i += 2)
1043  {
1044  blockAck.SetReceivedPacket(i, 1);
1045  }
1046  // 2nd byte of the bitmap: 10101010
1047  for (uint16_t i = startSeq2 + 9; i < startSeq2 + 16; i += 2)
1048  {
1049  blockAck.SetReceivedPacket(i, 1);
1050  }
1051  // 3rd byte of the bitmap: 00000000
1052  // 4th byte of the bitmap: 11111111
1053  for (uint16_t i = startSeq2 + 24; i < startSeq2 + 32; i++)
1054  {
1055  blockAck.SetReceivedPacket(i, 1);
1056  }
1057 
1058  /* 3rd Per AID TID Info subfield */
1059  uint16_t aid3 = 300;
1060  bool ackType3 = false;
1061  uint8_t tid3 = 3;
1062  uint16_t startSeq3 = 2000;
1063 
1064  blockAck.SetAid11(aid3, 2);
1065  blockAck.SetAckType(ackType3, 2);
1066  blockAck.SetTidInfo(tid3, 2);
1067  blockAck.SetStartingSequence(startSeq3, 2);
1068  // 1st byte of the bitmap: 01010101
1069  for (uint16_t i = startSeq3; i < startSeq3 + 8; i += 2)
1070  {
1071  blockAck.SetReceivedPacket(i, 2);
1072  }
1073  // 2nd byte of the bitmap: 10101010
1074  for (uint16_t i = startSeq3 + 9; i < startSeq3 + 16; i += 2)
1075  {
1076  blockAck.SetReceivedPacket(i, 2);
1077  }
1078  // 3rd byte of the bitmap: 00000000
1079  // 4th byte of the bitmap: 11111111
1080  for (uint16_t i = startSeq3 + 24; i < startSeq3 + 32; i++)
1081  {
1082  blockAck.SetReceivedPacket(i, 2);
1083  }
1084  // 5th byte of the bitmap: 00001111
1085  for (uint16_t i = startSeq3 + 32; i < startSeq3 + 36; i++)
1086  {
1087  blockAck.SetReceivedPacket(i, 2);
1088  }
1089  // 6th byte of the bitmap: 11110000
1090  for (uint16_t i = startSeq3 + 44; i < startSeq3 + 48; i++)
1091  {
1092  blockAck.SetReceivedPacket(i, 2);
1093  }
1094  // 7th byte of the bitmap: 00000000
1095  // 8th byte of the bitmap: 11111111
1096  for (uint16_t i = startSeq3 + 56; i < startSeq3 + 64; i++)
1097  {
1098  blockAck.SetReceivedPacket(i, 2);
1099  }
1100 
1101  /* 4th Per AID TID Info subfield */
1102  uint16_t aid4 = 400;
1103  bool ackType4 = false;
1104  uint8_t tid4 = 4;
1105  uint16_t startSeq4 = 3000;
1106 
1107  blockAck.SetAid11(aid4, 3);
1108  blockAck.SetAckType(ackType4, 3);
1109  blockAck.SetTidInfo(tid4, 3);
1110  blockAck.SetStartingSequence(startSeq4, 3);
1111  // 1st byte of the bitmap: 01010101
1112  for (uint16_t i = startSeq4; i < startSeq4 + 8; i += 2)
1113  {
1114  blockAck.SetReceivedPacket(i, 3);
1115  }
1116  // 2nd byte of the bitmap: 10101010
1117  for (uint16_t i = startSeq4 + 9; i < startSeq4 + 16; i += 2)
1118  {
1119  blockAck.SetReceivedPacket(i, 3);
1120  }
1121  // 3rd byte of the bitmap: 00000000
1122  // 4th byte of the bitmap: 11111111
1123  for (uint16_t i = startSeq4 + 24; i < startSeq4 + 32; i++)
1124  {
1125  blockAck.SetReceivedPacket(i, 3);
1126  }
1127  // 5th byte of the bitmap: 00001111
1128  for (uint16_t i = startSeq4 + 32; i < startSeq4 + 36; i++)
1129  {
1130  blockAck.SetReceivedPacket(i, 3);
1131  }
1132  // 6th byte of the bitmap: 11110000
1133  for (uint16_t i = startSeq4 + 44; i < startSeq4 + 48; i++)
1134  {
1135  blockAck.SetReceivedPacket(i, 3);
1136  }
1137  // 7th byte of the bitmap: 00000000
1138  // 8th byte of the bitmap: 11111111
1139  for (uint16_t i = startSeq4 + 56; i < startSeq4 + 64; i++)
1140  {
1141  blockAck.SetReceivedPacket(i, 3);
1142  }
1143  // 9th byte of the bitmap: 00000000
1144  // 10th byte of the bitmap: 11111111
1145  for (uint16_t i = startSeq4 + 72; i < startSeq4 + 80; i++)
1146  {
1147  blockAck.SetReceivedPacket(i, 3);
1148  }
1149  // 11th byte of the bitmap: 00000000
1150  // 12th byte of the bitmap: 11111111
1151  for (uint16_t i = startSeq4 + 88; i < startSeq4 + 96; i++)
1152  {
1153  blockAck.SetReceivedPacket(i, 3);
1154  }
1155  // 13th byte of the bitmap: 00000000
1156  // 14th byte of the bitmap: 11111111
1157  for (uint16_t i = startSeq4 + 104; i < startSeq4 + 112; i++)
1158  {
1159  blockAck.SetReceivedPacket(i, 3);
1160  }
1161  // 15th byte of the bitmap: 00000000
1162  // 16th byte of the bitmap: 11111111
1163  for (uint16_t i = startSeq4 + 120; i < startSeq4 + 128; i++)
1164  {
1165  blockAck.SetReceivedPacket(i, 3);
1166  }
1167 
1168  /* 5th Per AID TID Info subfield */
1169  uint16_t aid5 = 500;
1170  bool ackType5 = false;
1171  uint8_t tid5 = 5;
1172  uint16_t startSeq5 = 4000;
1173 
1174  blockAck.SetAid11(aid5, 4);
1175  blockAck.SetAckType(ackType5, 4);
1176  blockAck.SetTidInfo(tid5, 4);
1177  blockAck.SetStartingSequence(startSeq5, 4);
1178  // 1st byte of the bitmap: 01010101
1179  for (int i = startSeq5; i < startSeq5 + 8; i += 2)
1180  {
1181  blockAck.SetReceivedPacket(i, 4);
1182  }
1183  // 2nd byte of the bitmap: 10101010
1184  for (int i = startSeq5 + 9; i < startSeq5 + 16; i += 2)
1185  {
1186  blockAck.SetReceivedPacket(i, 4);
1187  }
1188  // 3rd byte of the bitmap: 00000000
1189  // 4th byte of the bitmap: 11111111
1190  for (int i = startSeq5 + 24; i < startSeq5 + 32; i++)
1191  {
1192  blockAck.SetReceivedPacket(i, 4);
1193  }
1194  // 5th byte of the bitmap: 00001111
1195  for (int i = startSeq5 + 32; i < startSeq5 + 36; i++)
1196  {
1197  blockAck.SetReceivedPacket(i, 4);
1198  }
1199  // 6th byte of the bitmap: 11110000
1200  for (int i = startSeq5 + 44; i < startSeq5 + 48; i++)
1201  {
1202  blockAck.SetReceivedPacket(i, 4);
1203  }
1204  // 7th byte of the bitmap: 00000000
1205  // 8th byte of the bitmap: 11111111
1206  for (int i = startSeq5 + 56; i < startSeq5 + 64; i++)
1207  {
1208  blockAck.SetReceivedPacket(i, 4);
1209  }
1210  // 9th byte of the bitmap: 00000000
1211  // 10th byte of the bitmap: 11111111
1212  for (int i = startSeq5 + 72; i < startSeq5 + 80; i++)
1213  {
1214  blockAck.SetReceivedPacket(i, 4);
1215  }
1216  // 11th byte of the bitmap: 00000000
1217  // 12th byte of the bitmap: 11111111
1218  for (int i = startSeq5 + 88; i < startSeq5 + 96; i++)
1219  {
1220  blockAck.SetReceivedPacket(i, 4);
1221  }
1222  // 13th byte of the bitmap: 00000000
1223  // 14th byte of the bitmap: 11111111
1224  for (int i = (startSeq5 + 104) % 4096; i < (startSeq5 + 112) % 4096; i++)
1225  {
1226  blockAck.SetReceivedPacket(i, 4);
1227  }
1228  // 15th byte of the bitmap: 00000000
1229  // 16th byte of the bitmap: 11111111
1230  for (int i = (startSeq5 + 120) % 4096; i < (startSeq5 + 128) % 4096; i++)
1231  {
1232  blockAck.SetReceivedPacket(i, 4);
1233  }
1234  // 17th byte of the bitmap: 00000000
1235  // 18th byte of the bitmap: 11111111
1236  for (int i = (startSeq5 + 136) % 4096; i < (startSeq5 + 144) % 4096; i++)
1237  {
1238  blockAck.SetReceivedPacket(i, 4);
1239  }
1240  // 19th byte of the bitmap: 00000000
1241  // 20th byte of the bitmap: 11111111
1242  for (int i = (startSeq5 + 152) % 4096; i < (startSeq5 + 160) % 4096; i++)
1243  {
1244  blockAck.SetReceivedPacket(i, 4);
1245  }
1246  // 21th byte of the bitmap: 00000000
1247  // 22th byte of the bitmap: 11111111
1248  for (int i = (startSeq5 + 168) % 4096; i < (startSeq5 + 176) % 4096; i++)
1249  {
1250  blockAck.SetReceivedPacket(i, 4);
1251  }
1252  // 23th byte of the bitmap: 00000000
1253  // 24th byte of the bitmap: 11111111
1254  for (int i = (startSeq5 + 184) % 4096; i < (startSeq5 + 192) % 4096; i++)
1255  {
1256  blockAck.SetReceivedPacket(i, 4);
1257  }
1258  // 25th byte of the bitmap: 00000000
1259  // 26th byte of the bitmap: 11111111
1260  for (int i = (startSeq5 + 200) % 4096; i < (startSeq5 + 208) % 4096; i++)
1261  {
1262  blockAck.SetReceivedPacket(i, 4);
1263  }
1264  // 27th byte of the bitmap: 00000000
1265  // 28th byte of the bitmap: 11111111
1266  for (int i = (startSeq5 + 216) % 4096; i < (startSeq5 + 224) % 4096; i++)
1267  {
1268  blockAck.SetReceivedPacket(i, 4);
1269  }
1270  // 29th byte of the bitmap: 00000000
1271  // 30th byte of the bitmap: 11111111
1272  for (int i = (startSeq5 + 232) % 4096; i < (startSeq5 + 240) % 4096; i++)
1273  {
1274  blockAck.SetReceivedPacket(i, 4);
1275  }
1276  // 31th byte of the bitmap: 00000000
1277  // 32th byte of the bitmap: 11111111
1278  for (int i = (startSeq5 + 248) % 4096; i < (startSeq5 + 256) % 4096; i++)
1279  {
1280  blockAck.SetReceivedPacket(i, 4);
1281  }
1282 
1283  /* 6th Per AID TID Info subfield */
1284  uint16_t aid6 = 2045;
1285  bool ackType6 = true;
1286  uint8_t tid6 = 6;
1287  Mac48Address address6("00:00:00:00:00:01");
1288 
1289  blockAck.SetAid11(aid6, 5);
1290  blockAck.SetAckType(ackType6, 5);
1291  blockAck.SetTidInfo(tid6, 5);
1292  blockAck.SetUnassociatedStaAddress(address6, 5);
1293 
1294  // Serialize the header
1295  Ptr<Packet> packet = Create<Packet>();
1296  packet->AddHeader(blockAck);
1297 
1298  // Deserialize the header
1299  CtrlBAckResponseHeader blockAckCopy;
1300  packet->RemoveHeader(blockAckCopy);
1301 
1302  // Check that the header has been correctly deserialized
1303  BlockAckType baTypeCopy = blockAckCopy.GetType();
1304 
1305  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_variant,
1306  BlockAckType::MULTI_STA,
1307  "Different block ack variant");
1308  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen.size(), 6, "Different number of bitmaps");
1309  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[0], 0, "Different length of the first bitmap");
1310  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[1], 4, "Different length of the second bitmap");
1311  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[2], 8, "Different length of the third bitmap");
1312  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[3], 16, "Different length of the fourth bitmap");
1313  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[4], 32, "Different length of the fifth bitmap");
1314  NS_TEST_EXPECT_MSG_EQ(baTypeCopy.m_bitmapLen[5], 8, "Different length for the sixth bitmap");
1315 
1316  /* Check 1st Per AID TID Info subfield */
1317  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(0),
1318  aid1,
1319  "Different AID for the first Per AID TID Info subfield");
1320  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(0),
1321  ackType1,
1322  "Different Ack Type for the first Per AID TID Info subfield");
1323  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(0),
1324  tid1,
1325  "Different TID for the first Per AID TID Info subfield");
1326 
1327  /* Check 2nd Per AID TID Info subfield */
1328  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(1),
1329  aid2,
1330  "Different AID for the second Per AID TID Info subfield");
1331  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(1),
1332  ackType2,
1333  "Different Ack Type for the second Per AID TID Info subfield");
1334  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(1),
1335  tid2,
1336  "Different TID for the second Per AID TID Info subfield");
1338  blockAckCopy.GetStartingSequence(1),
1339  startSeq2,
1340  "Different starting sequence number for the second Per AID TID Info subfield");
1341 
1342  auto& bitmap2 = blockAckCopy.GetBitmap(1);
1343  NS_TEST_EXPECT_MSG_EQ(bitmap2.size(),
1344  4,
1345  "Different bitmap length for the second Per AID TID Info subfield");
1347  bitmap2[0],
1348  0x55,
1349  "Error in the 1st byte of the bitmap for the second Per AID TID Info subfield");
1351  bitmap2[1],
1352  0xaa,
1353  "Error in the 2nd byte of the bitmap for the second Per AID TID Info subfield");
1355  bitmap2[2],
1356  0x00,
1357  "Error in the 3rd byte of the bitmap for the second Per AID TID Info subfield");
1359  bitmap2[3],
1360  0xff,
1361  "Error in the 4th byte of the bitmap for the second Per AID TID Info subfield");
1362 
1363  /* Check 3rd Per AID TID Info subfield */
1364  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(2),
1365  aid3,
1366  "Different AID for the third Per AID TID Info subfield");
1367  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(2),
1368  ackType3,
1369  "Different Ack Type for the third Per AID TID Info subfield");
1370  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(2),
1371  tid3,
1372  "Different TID for the third Per AID TID Info subfield");
1374  blockAckCopy.GetStartingSequence(2),
1375  startSeq3,
1376  "Different starting sequence number for the third Per AID TID Info subfield");
1377 
1378  auto& bitmap3 = blockAckCopy.GetBitmap(2);
1379  NS_TEST_EXPECT_MSG_EQ(bitmap3.size(),
1380  8,
1381  "Different bitmap length for the third Per AID TID Info subfield");
1383  bitmap3[0],
1384  0x55,
1385  "Error in the 1st byte of the bitmap for the third Per AID TID Info subfield");
1387  bitmap3[1],
1388  0xaa,
1389  "Error in the 2nd byte of the bitmap for the third Per AID TID Info subfield");
1391  bitmap3[2],
1392  0x00,
1393  "Error in the 3rd byte of the bitmap for the third Per AID TID Info subfield");
1395  bitmap3[3],
1396  0xff,
1397  "Error in the 4th byte of the bitmap for the third Per AID TID Info subfield");
1399  bitmap3[4],
1400  0x0f,
1401  "Error in the 5th byte of the bitmap for the third Per AID TID Info subfield");
1403  bitmap3[5],
1404  0xf0,
1405  "Error in the 6th byte of the bitmap for the third Per AID TID Info subfield");
1407  bitmap3[6],
1408  0x00,
1409  "Error in the 7th byte of the bitmap for the third Per AID TID Info subfield");
1411  bitmap3[7],
1412  0xff,
1413  "Error in the 8th byte of the bitmap for the third Per AID TID Info subfield");
1414 
1415  /* Check 4th Per AID TID Info subfield */
1416  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(3),
1417  aid4,
1418  "Different AID for the fourth Per AID TID Info subfield");
1419  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(3),
1420  ackType4,
1421  "Different Ack Type for the fourth Per AID TID Info subfield");
1422  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(3),
1423  tid4,
1424  "Different TID for the fourth Per AID TID Info subfield");
1426  blockAckCopy.GetStartingSequence(3),
1427  startSeq4,
1428  "Different starting sequence number for the fourth Per AID TID Info subfield");
1429 
1430  auto& bitmap4 = blockAckCopy.GetBitmap(3);
1431  NS_TEST_EXPECT_MSG_EQ(bitmap4.size(),
1432  16,
1433  "Different bitmap length for the fourth Per AID TID Info subfield");
1435  bitmap4[0],
1436  0x55,
1437  "Error in the 1st byte of the bitmap for the fourth Per AID TID Info subfield");
1439  bitmap4[1],
1440  0xaa,
1441  "Error in the 2nd byte of the bitmap for the fourth Per AID TID Info subfield");
1443  bitmap4[2],
1444  0x00,
1445  "Error in the 3rd byte of the bitmap for the fourth Per AID TID Info subfield");
1447  bitmap4[3],
1448  0xff,
1449  "Error in the 4th byte of the bitmap for the fourth Per AID TID Info subfield");
1451  bitmap4[4],
1452  0x0f,
1453  "Error in the 5th byte of the bitmap for the fourth Per AID TID Info subfield");
1455  bitmap4[5],
1456  0xf0,
1457  "Error in the 6th byte of the bitmap for the fourth Per AID TID Info subfield");
1459  bitmap4[6],
1460  0x00,
1461  "Error in the 7th byte of the bitmap for the fourth Per AID TID Info subfield");
1463  bitmap4[7],
1464  0xff,
1465  "Error in the 8th byte of the bitmap for the fourth Per AID TID Info subfield");
1467  bitmap4[8],
1468  0x00,
1469  "Error in the 9th byte of the bitmap for the fourth Per AID TID Info subfield");
1471  bitmap4[9],
1472  0xff,
1473  "Error in the 10th byte of the bitmap for the fourth Per AID TID Info subfield");
1475  bitmap4[10],
1476  0x00,
1477  "Error in the 11th byte of the bitmap for the fourth Per AID TID Info subfield");
1479  bitmap4[11],
1480  0xff,
1481  "Error in the 12th byte of the bitmap for the fourth Per AID TID Info subfield");
1483  bitmap4[12],
1484  0x00,
1485  "Error in the 13th byte of the bitmap for the fourth Per AID TID Info subfield");
1487  bitmap4[13],
1488  0xff,
1489  "Error in the 14th byte of the bitmap for the fourth Per AID TID Info subfield");
1491  bitmap4[14],
1492  0x00,
1493  "Error in the 15th byte of the bitmap for the fourth Per AID TID Info subfield");
1495  bitmap4[15],
1496  0xff,
1497  "Error in the 16th byte of the bitmap for the fourth Per AID TID Info subfield");
1498 
1499  /* Check 5th Per AID TID Info subfield */
1500  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(4),
1501  aid5,
1502  "Different AID for the fifth Per AID TID Info subfield");
1503  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(4),
1504  ackType5,
1505  "Different Ack Type for the fifth Per AID TID Info subfield");
1506  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(4),
1507  tid5,
1508  "Different TID for the fifth Per AID TID Info subfield");
1510  blockAckCopy.GetStartingSequence(4),
1511  startSeq5,
1512  "Different starting sequence number for the fifth Per AID TID Info subfield");
1513 
1514  auto& bitmap5 = blockAckCopy.GetBitmap(4);
1515  NS_TEST_EXPECT_MSG_EQ(bitmap5.size(),
1516  32,
1517  "Different bitmap length for the fifth Per AID TID Info subfield");
1519  bitmap5[0],
1520  0x55,
1521  "Error in the 1st byte of the bitmap for the fifth Per AID TID Info subfield");
1523  bitmap5[1],
1524  0xaa,
1525  "Error in the 2nd byte of the bitmap for the fifth Per AID TID Info subfield");
1527  bitmap5[2],
1528  0x00,
1529  "Error in the 3rd byte of the bitmap for the fifth Per AID TID Info subfield");
1531  bitmap5[3],
1532  0xff,
1533  "Error in the 4th byte of the bitmap for the fifth Per AID TID Info subfield");
1535  bitmap5[4],
1536  0x0f,
1537  "Error in the 5th byte of the bitmap for the fifth Per AID TID Info subfield");
1539  bitmap5[5],
1540  0xf0,
1541  "Error in the 6th byte of the bitmap for the fifth Per AID TID Info subfield");
1543  bitmap5[6],
1544  0x00,
1545  "Error in the 7th byte of the bitmap for the fifth Per AID TID Info subfield");
1547  bitmap5[7],
1548  0xff,
1549  "Error in the 8th byte of the bitmap for the fifth Per AID TID Info subfield");
1551  bitmap5[8],
1552  0x00,
1553  "Error in the 9th byte of the bitmap for the fifth Per AID TID Info subfield");
1555  bitmap5[9],
1556  0xff,
1557  "Error in the 10th byte of the bitmap for the fifth Per AID TID Info subfield");
1559  bitmap5[10],
1560  0x00,
1561  "Error in the 11th byte of the bitmap for the fifth Per AID TID Info subfield");
1563  bitmap5[11],
1564  0xff,
1565  "Error in the 12th byte of the bitmap for the fifth Per AID TID Info subfield");
1567  bitmap5[12],
1568  0x00,
1569  "Error in the 13th byte of the bitmap for the fifth Per AID TID Info subfield");
1571  bitmap5[13],
1572  0xff,
1573  "Error in the 14th byte of the bitmap for the fifth Per AID TID Info subfield");
1575  bitmap5[14],
1576  0x00,
1577  "Error in the 15th byte of the bitmap for the fifth Per AID TID Info subfield");
1579  bitmap5[15],
1580  0xff,
1581  "Error in the 16th byte of the bitmap for the fifth Per AID TID Info subfield");
1583  bitmap5[16],
1584  0x00,
1585  "Error in the 17th byte of the bitmap for the fifth Per AID TID Info subfield");
1587  bitmap5[17],
1588  0xff,
1589  "Error in the 18th byte of the bitmap for the fifth Per AID TID Info subfield");
1591  bitmap5[18],
1592  0x00,
1593  "Error in the 19th byte of the bitmap for the fifth Per AID TID Info subfield");
1595  bitmap5[19],
1596  0xff,
1597  "Error in the 20th byte of the bitmap for the fifth Per AID TID Info subfield");
1599  bitmap5[20],
1600  0x00,
1601  "Error in the 21th byte of the bitmap for the fifth Per AID TID Info subfield");
1603  bitmap5[21],
1604  0xff,
1605  "Error in the 22th byte of the bitmap for the fifth Per AID TID Info subfield");
1607  bitmap5[22],
1608  0x00,
1609  "Error in the 23th byte of the bitmap for the fifth Per AID TID Info subfield");
1611  bitmap5[23],
1612  0xff,
1613  "Error in the 24th byte of the bitmap for the fifth Per AID TID Info subfield");
1615  bitmap5[24],
1616  0x00,
1617  "Error in the 25th byte of the bitmap for the fifth Per AID TID Info subfield");
1619  bitmap5[25],
1620  0xff,
1621  "Error in the 26th byte of the bitmap for the fifth Per AID TID Info subfield");
1623  bitmap5[26],
1624  0x00,
1625  "Error in the 27th byte of the bitmap for the fifth Per AID TID Info subfield");
1627  bitmap5[27],
1628  0xff,
1629  "Error in the 28th byte of the bitmap for the fifth Per AID TID Info subfield");
1631  bitmap5[28],
1632  0x00,
1633  "Error in the 29th byte of the bitmap for the fifth Per AID TID Info subfield");
1635  bitmap5[29],
1636  0xff,
1637  "Error in the 30th byte of the bitmap for the fifth Per AID TID Info subfield");
1639  bitmap5[30],
1640  0x00,
1641  "Error in the 31th byte of the bitmap for the fifth Per AID TID Info subfield");
1643  bitmap5[31],
1644  0xff,
1645  "Error in the 32th byte of the bitmap for the fifth Per AID TID Info subfield");
1646 
1647  /* Check 6th Per AID TID Info subfield */
1648  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAid11(5),
1649  aid6,
1650  "Different AID for the sixth Per AID TID Info subfield");
1651  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetAckType(5),
1652  ackType6,
1653  "Different Ack Type for the sixth Per AID TID Info subfield");
1654  NS_TEST_EXPECT_MSG_EQ(blockAckCopy.GetTidInfo(5),
1655  tid6,
1656  "Different TID for the sixth Per AID TID Info subfield");
1658  blockAckCopy.GetUnassociatedStaAddress(5),
1659  address6,
1660  "Different starting sequence number for the sixth Per AID TID Info subfield");
1661 }
1662 
1708 {
1713  {
1720  void Trace(Time startTime, Time duration, uint8_t linkId);
1722  };
1723 
1724  public:
1731 
1732  void DoRun() override;
1733 
1734  private:
1735  bool m_txop;
1736  uint32_t m_received;
1737  uint16_t m_txTotal;
1738  uint16_t m_txSinceBar;
1740  uint16_t m_nBar;
1741  uint16_t m_nBa;
1742 
1749  void L7Receive(std::string context, Ptr<const Packet> p, const Address& adr);
1756  void Transmit(std::string context, Ptr<const Packet> p, double power);
1763  void Receive(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1764 };
1765 
1766 void
1768  Time duration,
1769  uint8_t linkId)
1770 {
1771  if (duration > m_max)
1772  {
1773  m_max = duration;
1774  }
1775 }
1776 
1778  : TestCase("Test case for Block Ack Policy with aggregation disabled"),
1779  m_txop(txop),
1780  m_received(0),
1781  m_txTotal(0),
1782  m_txSinceBar(0),
1783  m_nBar(0),
1784  m_nBa(0)
1785 {
1786 }
1787 
1789 {
1790 }
1791 
1792 void
1795  const Address& adr)
1796 {
1797  if (p->GetSize() == 1400)
1798  {
1799  m_received++;
1800  }
1801 }
1802 
1803 void
1805 {
1806  WifiMacHeader hdr;
1807  p->PeekHeader(hdr);
1808 
1809  if (m_nBar < 2 && (m_txSinceBar == 9 || m_txTotal == 14))
1810  {
1811  NS_TEST_ASSERT_MSG_EQ(hdr.IsBlockAckReq(), true, "Didn't get a BlockAckReq when expected");
1812  }
1813  else
1814  {
1815  NS_TEST_ASSERT_MSG_EQ(hdr.IsBlockAckReq(), false, "Got a BlockAckReq when not expected");
1816  }
1817 
1818  if (hdr.IsQosData())
1819  {
1820  m_txTotal++;
1821  if (hdr.IsQosBlockAck())
1822  {
1823  m_txSinceBar++;
1824  }
1825 
1826  if (!m_txop)
1827  {
1829  true,
1830  "Unexpected QoS ack policy");
1831  }
1832  else
1833  {
1835  true,
1836  "Unexpected QoS ack policy");
1837  }
1838  }
1839  else if (hdr.IsBlockAckReq())
1840  {
1841  m_txSinceBar = 0;
1842  m_nBar++;
1843  }
1844 }
1845 
1846 void
1849  RxPowerWattPerChannelBand rxPowersW)
1850 {
1851  WifiMacHeader hdr;
1852  p->PeekHeader(hdr);
1853 
1854  if (hdr.IsBlockAck())
1855  {
1856  m_nBa++;
1857  }
1858 }
1859 
1860 void
1862 {
1863  NodeContainer wifiStaNode;
1864  wifiStaNode.Create(1);
1865 
1867  wifiApNode.Create(1);
1868 
1869  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
1871  phy.SetChannel(channel.Create());
1872 
1873  WifiHelper wifi;
1874  wifi.SetStandard(WIFI_STANDARD_80211n);
1875  Config::SetDefault("ns3::WifiDefaultAckManager::BaThreshold", DoubleValue(0.125));
1876  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1877 
1879  Ssid ssid = Ssid("ns-3-ssid");
1880  mac.SetType("ns3::StaWifiMac",
1881  "BE_MaxAmsduSize",
1882  UintegerValue(0),
1883  "BE_MaxAmpduSize",
1884  UintegerValue(0),
1885  "Ssid",
1886  SsidValue(ssid),
1887  /* setting blockack threshold for sta's BE queue */
1888  "BE_BlockAckThreshold",
1889  UintegerValue(2),
1890  "ActiveProbing",
1891  BooleanValue(false));
1892 
1894  staDevices = wifi.Install(phy, mac, wifiStaNode);
1895 
1896  mac.SetType("ns3::ApWifiMac",
1897  "BE_MaxAmsduSize",
1898  UintegerValue(0),
1899  "BE_MaxAmpduSize",
1900  UintegerValue(0),
1901  "Ssid",
1902  SsidValue(ssid),
1903  "BeaconGeneration",
1904  BooleanValue(true));
1905 
1907  apDevices = wifi.Install(phy, mac, wifiApNode);
1908 
1910  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1911 
1912  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1913  positionAlloc->Add(Vector(1.0, 0.0, 0.0));
1914  mobility.SetPositionAllocator(positionAlloc);
1915 
1916  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1917  mobility.Install(wifiApNode);
1918  mobility.Install(wifiStaNode);
1919 
1920  Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
1921  Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
1922 
1923  // Disable A-MPDU aggregation
1924  sta_device->GetMac()->SetAttribute("BE_MaxAmpduSize", UintegerValue(0));
1925  TxopDurationTracer txopTracer;
1926 
1927  if (m_txop)
1928  {
1929  PointerValue ptr;
1930  sta_device->GetMac()->GetAttribute("BE_Txop", ptr);
1931  ptr.Get<QosTxop>()->TraceConnectWithoutContext(
1932  "TxopTrace",
1933  MakeCallback(&TxopDurationTracer::Trace, &txopTracer));
1934 
1935  // set the TXOP limit on BE AC
1936  ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
1937  ptr.Get<QosTxop>()->SetTxopLimit(MicroSeconds(4800));
1938  }
1939 
1940  PacketSocketAddress socket;
1941  socket.SetSingleDevice(sta_device->GetIfIndex());
1942  socket.SetPhysicalAddress(ap_device->GetAddress());
1943  socket.SetProtocol(1);
1944 
1945  // give packet socket powers to nodes.
1946  PacketSocketHelper packetSocket;
1947  packetSocket.Install(wifiStaNode);
1948  packetSocket.Install(wifiApNode);
1949 
1950  // the first client application generates a single packet, which is sent
1951  // with the normal ack policy because there are no other packets queued
1952  Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient>();
1953  client1->SetAttribute("PacketSize", UintegerValue(1400));
1954  client1->SetAttribute("MaxPackets", UintegerValue(1));
1955  client1->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
1956  client1->SetRemote(socket);
1957  wifiStaNode.Get(0)->AddApplication(client1);
1958  client1->SetStartTime(Seconds(1));
1959  client1->SetStopTime(Seconds(3.0));
1960 
1961  // the second client application generates 13 packets. Even if when the first
1962  // packet is queued the queue is empty, the first packet is not transmitted
1963  // immediately, but the EDCAF waits for the next slot boundary. At that time,
1964  // other packets have been queued, hence a BA agreement is established first.
1965  Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient>();
1966  client2->SetAttribute("PacketSize", UintegerValue(1400));
1967  client2->SetAttribute("MaxPackets", UintegerValue(13));
1968  client2->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
1969  client2->SetRemote(socket);
1970  wifiStaNode.Get(0)->AddApplication(client2);
1971  client2->SetStartTime(Seconds(1.5));
1972  client2->SetStopTime(Seconds(3.0));
1973 
1974  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
1975  server->SetLocal(socket);
1976  wifiApNode.Get(0)->AddApplication(server);
1977  server->SetStartTime(Seconds(0.0));
1978  server->SetStopTime(Seconds(4.0));
1979 
1980  Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
1982  Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyTxBegin",
1984  Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyRxBegin",
1986 
1987  Simulator::Stop(Seconds(5));
1988  Simulator::Run();
1989 
1990  Simulator::Destroy();
1991 
1992  // The client applications generate 14 packets, so we expect that the wifi PHY
1993  // layer transmits 14 MPDUs, the server application receives 14 packets, and
1994  // two BARs are transmitted.
1995  NS_TEST_EXPECT_MSG_EQ(m_txTotal, 14, "Unexpected number of transmitted packets");
1996  NS_TEST_EXPECT_MSG_EQ(m_received, 14, "Unexpected number of received packets");
1997  NS_TEST_EXPECT_MSG_EQ(m_nBar, 2, "Unexpected number of Block Ack Requests");
1998  NS_TEST_EXPECT_MSG_EQ(m_nBa, 2, "Unexpected number of Block Ack Responses");
1999  if (m_txop)
2000  {
2001  NS_TEST_EXPECT_MSG_LT(txopTracer.m_max, MicroSeconds(4800), "TXOP duration exceeded!");
2002  NS_TEST_EXPECT_MSG_GT(txopTracer.m_max,
2003  MicroSeconds(3008),
2004  "The maximum TXOP duration is too short!");
2005  }
2006 }
2007 
2015 {
2016  public:
2018 };
2019 
2021  : TestSuite("wifi-block-ack", UNIT)
2022 {
2023  AddTestCase(new PacketBufferingCaseA, TestCase::QUICK);
2024  AddTestCase(new PacketBufferingCaseB, TestCase::QUICK);
2025  AddTestCase(new OriginatorBlockAckWindowTest, TestCase::QUICK);
2026  AddTestCase(new CtrlBAckResponseHeaderTest, TestCase::QUICK);
2027  AddTestCase(new BlockAckRecipientBufferTest(0), TestCase::QUICK);
2028  AddTestCase(new BlockAckRecipientBufferTest(4090), TestCase::QUICK);
2029  AddTestCase(new MultiStaCtrlBAckResponseHeaderTest, TestCase::QUICK);
2030  AddTestCase(new BlockAckAggregationDisabledTest(false), TestCase::QUICK);
2031  AddTestCase(new BlockAckAggregationDisabledTest(true), TestCase::QUICK);
2032 }
2033 
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 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:101
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.
Definition: ctrl-headers.h:203
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:42
an EUI-48 address
Definition: mac48-address.h:46
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:169
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:244
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...
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get() const
Definition: pointer.h:202
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
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.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
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.
Ptr< WifiMac > GetMac() const
uint32_t GetIfIndex() const override
Address GetAddress() 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:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:790
#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:956
#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:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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:171
@ WIFI_STANDARD_80211n
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:704
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
Definition: wifi-utils.h:185
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
staDevices
Definition: third.py:100
ssid
Definition: third.py:93
channel
Definition: third.py:88
mac
Definition: third.py:92
wifi
Definition: third.py:95
apDevices
Definition: third.py:103
wifiApNode
Definition: third.py:86
mobility
Definition: third.py:105
phy
Definition: third.py:89
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.