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 
42 /**
43  * \ingroup wifi-test
44  * \ingroup tests
45  *
46  * \brief Packet Buffering Case A
47  *
48  * This simple test verifies the correctness of buffering for packets received
49  * under block ack. In order to completely understand this example is important to cite
50  * section 9.10.3 in IEEE802.11 standard:
51  *
52  * "[...] The sequence number space is considered divided into two parts, one of which
53  * is “old” and one of which is “new” by means of a boundary created by adding half the
54  * sequence number range to the current start of receive window (modulo 2^12)."
55  */
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  */
79 class PacketBufferingCaseA : public TestCase
80 {
81 public:
82   PacketBufferingCaseA ();
83   virtual ~PacketBufferingCaseA ();
84 private:
85   void DoRun (void) override;
86   std::list<uint16_t> m_expectedBuffer; ///< expected test buffer
87 };
88 
PacketBufferingCaseA()89 PacketBufferingCaseA::PacketBufferingCaseA ()
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 
~PacketBufferingCaseA()99 PacketBufferingCaseA::~PacketBufferingCaseA ()
100 {
101 }
102 
103 void
DoRun(void)104 PacketBufferingCaseA::DoRun (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 
147 /**
148  * \ingroup wifi-test
149  * \ingroup tests
150  *
151  * \brief Packet Buffering Case B
152  *
153  * ----- = old packets
154  * +++++ = new packets
155  *
156  *  CASE B: startSeq > endSeq
157  *                         -    +    +
158  *  initial buffer state: 256 64000 16
159  *
160  *
161  *    0                            4095
162  *    |++++++|----------------|++++++|
163  *           ^                ^
164  *           | endSeq = 10    | startSeq
165  *
166  *  first received packet's sequence control = 240 (seqNum = 15, fragNum = 0)  -
167  *  second received packet's sequence control = 241 (seqNum = 15, fragNum = 1) -
168  *  third received packet's sequence control = 64800 (seqNum = 4050, fragNum = 0) +
169  *  240 is an old packet should be inserted at the buffer's begin.
170  *  241 is an old packet: second segment of the above packet.
171  *  4050 is a new packet: it should be inserted between 64000 and 16.
172  *
173  *  expected buffer state: 240 241 256 64000 64800 16
174  *
175  */
176 class PacketBufferingCaseB : public TestCase
177 {
178 public:
179   PacketBufferingCaseB ();
180   virtual ~PacketBufferingCaseB ();
181 private:
182   void DoRun (void) override;
183   std::list<uint16_t> m_expectedBuffer; ///< expected test buffer
184 };
185 
PacketBufferingCaseB()186 PacketBufferingCaseB::PacketBufferingCaseB ()
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 
~PacketBufferingCaseB()197 PacketBufferingCaseB::~PacketBufferingCaseB ()
198 {
199 }
200 
201 void
DoRun(void)202 PacketBufferingCaseB::DoRun (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 
257 /**
258  * \ingroup wifi-test
259  * \ingroup tests
260  *
261  * \brief Test for the originator block ack window
262  */
263 class OriginatorBlockAckWindowTest : public TestCase
264 {
265 public:
266   OriginatorBlockAckWindowTest ();
267 private:
268   void DoRun (void) override;
269 };
270 
OriginatorBlockAckWindowTest()271 OriginatorBlockAckWindowTest::OriginatorBlockAckWindowTest ()
272   : TestCase ("Check the correctness of the originator block ack window")
273 {
274 }
275 
276 void
DoRun(void)277 OriginatorBlockAckWindowTest::DoRun (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;
297   hdr.SetType (WIFI_MAC_QOSDATA);
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 
552 /**
553  * \ingroup wifi-test
554  * \ingroup tests
555  *
556  * \brief Test for block ack header
557  */
558 class CtrlBAckResponseHeaderTest : public TestCase
559 {
560 public:
561   CtrlBAckResponseHeaderTest ();
562 private:
563   void DoRun (void) override;
564   CtrlBAckResponseHeader m_blockAckHdr; ///< block ack header
565 };
566 
CtrlBAckResponseHeaderTest()567 CtrlBAckResponseHeaderTest::CtrlBAckResponseHeaderTest ()
568   : TestCase ("Check the correctness of block ack compressed bitmap")
569 {
570 }
571 
572 void
DoRun(void)573 CtrlBAckResponseHeaderTest::DoRun (void)
574 {
575   m_blockAckHdr.SetType (BlockAckType::COMPRESSED);
576 
577   //Case 1: startSeq < endSeq
578   //          179        242
579   m_blockAckHdr.SetStartingSequence (179);
580   for (uint16_t i = 179; i < 220; i++)
581     {
582       m_blockAckHdr.SetReceivedPacket (i);
583     }
584   for (uint16_t i = 225; i <= 242; i++)
585     {
586       m_blockAckHdr.SetReceivedPacket (i);
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");
596   m_blockAckHdr.SetReceivedPacket (1500);
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 
609   m_blockAckHdr.ResetBitmap ();
610 
611   //Case 2: startSeq > endSeq
612   //          4090       58
613   m_blockAckHdr.SetStartingSequence (4090);
614   for (uint16_t i = 4090; i != 10; i = (i + 1) % 4096)
615     {
616       m_blockAckHdr.SetReceivedPacket (i);
617     }
618   for (uint16_t i = 22; i < 25; i++)
619     {
620       m_blockAckHdr.SetReceivedPacket (i);
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");
630   m_blockAckHdr.SetReceivedPacket (80);
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 
647 /**
648  * \ingroup wifi-test
649  * \ingroup tests
650  *
651  * \brief Test for recipient reordering buffer operations
652  */
653 class BlockAckRecipientBufferTest : public TestCase
654 {
655 public:
656   /**
657    * \brief Constructor
658    * \param ssn the Starting Sequence Number used to initialize WinStartB
659    */
660   BlockAckRecipientBufferTest (uint16_t ssn);
661   virtual ~BlockAckRecipientBufferTest ();
662 
663   void DoRun (void) override;
664 
665   /**
666    * Keep track of MPDUs that are forwarded up.
667    *
668    * \param mpdu an MPDU that is forwarded up
669    */
670   void ForwardUp (Ptr<WifiMacQueueItem> mpdu);
671 
672 private:
673   uint16_t m_ssn;                          //!< the Starting Sequence Number used to initialize WinStartB
674   std::list<Ptr<WifiMacQueueItem>> m_fwup; //!< list of MPDUs that have been forwarded up
675 };
676 
BlockAckRecipientBufferTest(uint16_t ssn)677 BlockAckRecipientBufferTest::BlockAckRecipientBufferTest (uint16_t ssn)
678   : TestCase ("Test case for Block Ack recipient reordering buffer operations"),
679     m_ssn (ssn)
680 {
681 }
682 
~BlockAckRecipientBufferTest()683 BlockAckRecipientBufferTest::~BlockAckRecipientBufferTest ()
684 {
685 }
686 
687 void
ForwardUp(Ptr<WifiMacQueueItem> mpdu)688 BlockAckRecipientBufferTest::ForwardUp (Ptr<WifiMacQueueItem> mpdu)
689 {
690   m_fwup.push_back (mpdu);
691 }
692 
693 void
DoRun(void)694 BlockAckRecipientBufferTest::DoRun (void)
695 {
696   Ptr<MacRxMiddle> rxMiddle = Create<MacRxMiddle> ();
697   rxMiddle->SetForwardCallback (MakeCallback (&BlockAckRecipientBufferTest::ForwardUp, this));
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;
705   hdr.SetType (WIFI_MAC_QOSDATA);
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
725   hdr.SetSequenceNumber ((m_ssn + 4) % SEQNO_SPACE_SIZE);
726   agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
727   hdr.SetSequenceNumber ((m_ssn + 2) % SEQNO_SPACE_SIZE);
728   agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
729   hdr.SetSequenceNumber ((m_ssn + 5) % SEQNO_SPACE_SIZE);
730   agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
731   hdr.SetSequenceNumber ((m_ssn + 3) % SEQNO_SPACE_SIZE);
732   agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
733   hdr.SetSequenceNumber ((m_ssn + 10) % SEQNO_SPACE_SIZE);
734   agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
735   hdr.SetSequenceNumber ((m_ssn + 7) % SEQNO_SPACE_SIZE);
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)
749   hdr.SetSequenceNumber ((m_ssn + 2) % SEQNO_SPACE_SIZE);
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
760   hdr.SetSequenceNumber ((m_ssn + 1) % SEQNO_SPACE_SIZE);
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)
798   hdr.SetSequenceNumber ((m_ssn + 17) % SEQNO_SPACE_SIZE);
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
832   hdr.SetSequenceNumber ((m_ssn + 9) % SEQNO_SPACE_SIZE);
833   agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
834   hdr.SetSequenceNumber ((m_ssn + 11) % SEQNO_SPACE_SIZE);
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 
868 /**
869  * \ingroup wifi-test
870  * \ingroup tests
871  *
872  * \brief Test for Multi-STA block ack header
873  */
874 class MultiStaCtrlBAckResponseHeaderTest : public TestCase
875 {
876 public:
877   MultiStaCtrlBAckResponseHeaderTest ();
878 private:
879   virtual void DoRun (void);
880 };
881 
MultiStaCtrlBAckResponseHeaderTest()882 MultiStaCtrlBAckResponseHeaderTest::MultiStaCtrlBAckResponseHeaderTest ()
883   : TestCase ("Check the correctness of Multi-STA block ack")
884 {
885 }
886 
887 void
DoRun(void)888 MultiStaCtrlBAckResponseHeaderTest::DoRun (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 
1297 /**
1298  * \ingroup wifi-test
1299  * \ingroup tests
1300  *
1301  * \brief Test for Block Ack Policy with aggregation disabled
1302  *
1303  * This test aims to check the Block Ack policy when A-MPDU aggregation is disabled.
1304  * In this case, a QoS station can transmit multiple QoS data frames before requesting
1305  * a Block Ack through a Block Ack Request frame. If the AC is granted a non-null TXOP
1306  * limit, MPDUs can be separated by a SIFS.
1307  *
1308  * In this test, an HT STA sends 14 packets to an HT AP. The ack policy selector is
1309  * configured so that a Block Ack is requested once 8 (= 0.125 * 64) MPDUs are sent
1310  * in addition to the MPDU having the starting sequence number. The block ack threshold
1311  * is set to 2, hence a block ack agreement is established when there are at least two
1312  * packets in the EDCA queue.
1313  *
1314  * When the TXOP limit is null:
1315  * - the first packet is sent with Normal Ack policy because the BA agreement has not
1316  *   been established yet (there are no queued packets when the first one arrives);
1317  * - packets from the 2nd to the 10th are sent with Block Ack policy (and hence
1318  *   are not immediately acknowledged);
1319  * - after the 10th packet, a Block Ack Request is sent, followed by a Block Ack;
1320  * - the remaining 4 packets are sent with Block Ack policy (and hence
1321  *   are not immediately acknowledged);
1322  * - the last packet is followed by a Block Ack Request because there are no more
1323  *   packets in the EDCA queue and hence a response is needed independently of
1324  *   the number of outstanding MPDUs.
1325  *
1326  * When the TXOP is not null (and long enough to include the transmission of all packets):
1327  * - the first packet is sent with Normal Ack policy because the BA agreement has not
1328  *   been established yet (there are no queued packets when the first one arrives);
1329  * - the second packet is sent with Normal Ack Policy because the first packet sent in
1330  *   a TXOP shall request an immediate response and no previous MPDUs have to be
1331  *   acknowledged;
1332  * - packets from the 3rd to the 11th are sent with Block Ack policy (and hence
1333  *   are not immediately acknowledged);
1334  * - after the 11th packet, a Block Ack Request is sent, followed by a Block Ack;
1335  * - the remaining 3 packets are sent with Block Ack policy (and hence
1336  *   are not immediately acknowledged);
1337  * - the last packet is followed by a Block Ack Request because there are no more
1338  *   packets in the EDCA queue and hence a response is needed independently of
1339  *   the number of outstanding MPDUs.
1340  */
1341 class BlockAckAggregationDisabledTest : public TestCase
1342 {
1343   /**
1344   * Keeps the maximum duration among all TXOPs
1345   */
1346   struct TxopDurationTracer
1347   {
1348     /**
1349      * Callback for the TxopTrace trace
1350      * \param startTime TXOP start time
1351      * \param duration TXOP duration
1352      */
1353     void Trace (Time startTime, Time duration);
1354     Time m_max {Seconds (0)};  ///< max TXOP duration
1355   };
1356 
1357 public:
1358   /**
1359    * \brief Constructor
1360    * \param txop true for non-null TXOP limit
1361    */
1362   BlockAckAggregationDisabledTest (bool txop);
1363   virtual ~BlockAckAggregationDisabledTest ();
1364 
1365   void DoRun (void) override;
1366 
1367 
1368 private:
1369   bool m_txop; ///< true for non-null TXOP limit
1370   uint32_t m_received; ///< received packets
1371   uint16_t m_txTotal; ///< transmitted data packets
1372   uint16_t m_txSinceBar; ///< packets transmitted since the agreement was established
1373                          ///< or the last block ack was received
1374   uint16_t m_nBar; ///< transmitted BlockAckReq frames
1375   uint16_t m_nBa; ///< received BlockAck frames
1376 
1377   /**
1378    * Function to trace packets received by the server application
1379    * \param context the context
1380    * \param p the packet
1381    * \param adr the address
1382    */
1383   void L7Receive (std::string context, Ptr<const Packet> p, const Address &adr);
1384   /**
1385    * Callback invoked when PHY transmits a packet
1386    * \param context the context
1387    * \param p the packet
1388    * \param power the tx power
1389    */
1390   void Transmit (std::string context, Ptr<const Packet> p, double power);
1391   /**
1392    * Callback invoked when PHY receives a packet
1393    * \param context the context
1394    * \param p the packet
1395    * \param rxPowersW the received power per channel band in watts
1396    */
1397   void Receive (std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1398 };
1399 
1400 void
Trace(Time startTime,Time duration)1401 BlockAckAggregationDisabledTest::TxopDurationTracer::Trace (Time startTime, Time duration)
1402 {
1403   if (duration > m_max)
1404     {
1405       m_max = duration;
1406     }
1407 }
1408 
BlockAckAggregationDisabledTest(bool txop)1409 BlockAckAggregationDisabledTest::BlockAckAggregationDisabledTest (bool txop)
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 
~BlockAckAggregationDisabledTest()1420 BlockAckAggregationDisabledTest::~BlockAckAggregationDisabledTest ()
1421 {
1422 }
1423 
1424 void
L7Receive(std::string context,Ptr<const Packet> p,const Address & adr)1425 BlockAckAggregationDisabledTest::L7Receive (std::string context, Ptr<const Packet> p, const Address &adr)
1426 {
1427   if (p->GetSize () == 1400)
1428     {
1429       m_received++;
1430     }
1431 }
1432 
1433 void
Transmit(std::string context,Ptr<const Packet> p,double power)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
Receive(std::string context,Ptr<const Packet> p,RxPowerWattPerChannelBand rxPowersW)1473 BlockAckAggregationDisabledTest::Receive (std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW)
1474 {
1475   WifiMacHeader hdr;
1476   p->PeekHeader (hdr);
1477 
1478   if (hdr.IsBlockAck ())
1479     {
1480       m_nBa++;
1481     }
1482 }
1483 
1484 void
DoRun(void)1485 BlockAckAggregationDisabledTest::DoRun (void)
1486 {
1487   NodeContainer wifiStaNode;
1488   wifiStaNode.Create (1);
1489 
1490   NodeContainer wifiApNode;
1491   wifiApNode.Create (1);
1492 
1493   YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
1494   YansWifiPhyHelper phy;
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 
1502   WifiMacHelper mac;
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 
1512   NetDeviceContainer staDevices;
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 
1521   NetDeviceContainer apDevices;
1522   apDevices = wifi.Install (phy, mac, wifiApNode);
1523 
1524   MobilityHelper mobility;
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 
1618 /**
1619  * \ingroup wifi-test
1620  * \ingroup tests
1621  *
1622  * \brief Block Ack Test Suite
1623  */
1624 class BlockAckTestSuite : public TestSuite
1625 {
1626 public:
1627   BlockAckTestSuite ();
1628 };
1629 
BlockAckTestSuite()1630 BlockAckTestSuite::BlockAckTestSuite ()
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 
1644 static BlockAckTestSuite g_blockAckTestSuite; ///< the test suite
1645