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