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