A Discrete-Event Network Simulator
API
block-ack-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009, 2010 MIRKO BANCHI
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mirko Banchi <mk.banchi@gmail.com>
19  */
20 
21 #include "ns3/test.h"
22 #include "ns3/string.h"
23 #include "ns3/qos-utils.h"
24 #include "ns3/ctrl-headers.h"
25 #include "ns3/packet.h"
26 #include "ns3/wifi-net-device.h"
27 #include "ns3/ap-wifi-mac.h"
28 #include "ns3/wifi-mac-header.h"
29 #include "ns3/mobility-helper.h"
30 #include "ns3/yans-wifi-helper.h"
31 #include "ns3/packet-socket-server.h"
32 #include "ns3/packet-socket-client.h"
33 #include "ns3/packet-socket-helper.h"
34 #include "ns3/config.h"
35 #include "ns3/pointer.h"
36 #include "ns3/recipient-block-ack-agreement.h"
37 #include "ns3/mac-rx-middle.h"
38 #include <list>
39 
40 using namespace ns3;
41 
56 //-------------------------------------------------------------------------------------
57 
58 /* ----- = old packets
59  * +++++ = new packets
60  *
61  * CASE A: startSeq < endSeq
62  * - - +
63  * initial buffer state: 0 16 56000
64  *
65  *
66  * 0 4095
67  * |------|++++++++++++++++|-----|
68  * ^ ^
69  * | startSeq | endSeq = 4000
70  *
71  * first received packet's sequence control = 64016 (seqNum = 4001, fragNum = 0) -
72  * second received packet's sequence control = 63984 (seqNum = 3999, fragNum = 0) +
73  * 4001 is older seq number so this packet should be inserted at the buffer's begin.
74  * 3999 is previous element of older of new packets: it should be inserted at the end of buffer.
75  *
76  * expected buffer state: 64016 0 16 56000 63984
77  *
78  */
80 {
81 public:
83  virtual ~PacketBufferingCaseA ();
84 private:
85  virtual void DoRun (void);
86  std::list<uint16_t> m_expectedBuffer;
87 };
88 
90  : TestCase ("Check correct order of buffering when startSequence < endSeq")
91 {
92  m_expectedBuffer.push_back (64016);
93  m_expectedBuffer.push_back (0);
94  m_expectedBuffer.push_back (16);
95  m_expectedBuffer.push_back (56000);
96  m_expectedBuffer.push_back (63984);
97 }
98 
100 {
101 }
102 
103 void
105 {
106  std::list<uint16_t> m_buffer;
107  std::list<uint16_t>::iterator i,j;
108  m_buffer.push_back (0);
109  m_buffer.push_back (16);
110  m_buffer.push_back (56000);
111 
112  uint16_t endSeq = 4000;
113 
114  uint16_t receivedSeq = 4001 * 16;
115  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
116  /* cycle to right position for this packet */
117  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
118  {
119  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
120  {
121  //position found
122  break;
123  }
124  }
125  m_buffer.insert (i, receivedSeq);
126 
127  receivedSeq = 3999 * 16;
128  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
129  /* cycle to right position for this packet */
130  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
131  {
132  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
133  {
134  //position found
135  break;
136  }
137  }
138  m_buffer.insert (i, receivedSeq);
139 
140  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
141  {
142  NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
143  }
144 }
145 
146 
177 {
178 public:
180  virtual ~PacketBufferingCaseB ();
181 private:
182  virtual void DoRun (void);
183  std::list<uint16_t> m_expectedBuffer;
184 };
185 
187  : TestCase ("Check correct order of buffering when startSequence > endSeq")
188 {
189  m_expectedBuffer.push_back (240);
190  m_expectedBuffer.push_back (241);
191  m_expectedBuffer.push_back (256);
192  m_expectedBuffer.push_back (64000);
193  m_expectedBuffer.push_back (64800);
194  m_expectedBuffer.push_back (16);
195 }
196 
198 {
199 }
200 
201 void
203 {
204  std::list<uint16_t> m_buffer;
205  std::list<uint16_t>::iterator i,j;
206  m_buffer.push_back (256);
207  m_buffer.push_back (64000);
208  m_buffer.push_back (16);
209 
210  uint16_t endSeq = 10;
211 
212  uint16_t receivedSeq = 15 * 16;
213  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
214  /* cycle to right position for this packet */
215  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
216  {
217  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
218  {
219  //position found
220  break;
221  }
222  }
223  m_buffer.insert (i, receivedSeq);
224 
225  receivedSeq = 15 * 16 + 1;
226  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
227  /* cycle to right position for this packet */
228  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
229  {
230  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
231  {
232  //position found
233  break;
234  }
235  }
236  m_buffer.insert (i, receivedSeq);
237 
238  receivedSeq = 4050 * 16;
239  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
240  /* cycle to right position for this packet */
241  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
242  {
243  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
244  {
245  //position found
246  break;
247  }
248  }
249  m_buffer.insert (i, receivedSeq);
250 
251  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
252  {
253  NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
254  }
255 }
256 
264 {
265 public:
267 private:
268  virtual void DoRun ();
269 };
270 
272  : TestCase ("Check the correctness of the originator block ack window")
273 {
274 }
275 
276 void
278 {
279  uint16_t winSize = 16;
280  uint16_t startingSeq = 4090;
281 
282  OriginatorBlockAckAgreement agreement (Mac48Address ("00:00:00:00:00:01"), 0);
283  agreement.SetBufferSize (winSize);
284  agreement.SetStartingSequence (startingSeq);
285  agreement.InitTxWindow ();
286 
287  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.GetWinSize (), winSize, "Incorrect window size");
288  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.GetWinStart (), startingSeq, "Incorrect winStart");
289  // check that all the elements in the window are cleared
290  for (uint16_t i = 0; i < winSize; i++)
291  {
292  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Not all flags are cleared after initialization");
293  }
294 
295  // Notify the acknowledgment of 5 packets
296  WifiMacHeader hdr;
298  Ptr<WifiMacQueueItem> mpdu = Create<WifiMacQueueItem> (Create<Packet> (), hdr);
299  uint16_t seqNumber = startingSeq;
300  mpdu->GetHeader ().SetSequenceNumber (seqNumber);
301  agreement.NotifyAckedMpdu (mpdu);
302 
303  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
304  agreement.NotifyAckedMpdu (mpdu);
305 
306  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
307  agreement.NotifyAckedMpdu (mpdu);
308 
309  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
310  agreement.NotifyAckedMpdu (mpdu);
311 
312  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
313  agreement.NotifyAckedMpdu (mpdu);
314 
315  // the current window must look like this:
316  //
317  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
318  // ^
319  // |
320  // HEAD
321 
322  startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
323  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after 5 acknowledgments");
324  for (uint16_t i = 0; i < winSize; i++)
325  {
326  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Not all flags are cleared after 5 acknowledgments");
327  }
328 
329  // the next MPDU is not acknowledged, hence the window is blocked while the
330  // subsequent 4 MPDUs are acknowledged
331  ++seqNumber %= SEQNO_SPACE_SIZE;
332  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
333  agreement.NotifyAckedMpdu (mpdu);
334 
335  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
336  agreement.NotifyAckedMpdu (mpdu);
337 
338  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
339  agreement.NotifyAckedMpdu (mpdu);
340 
341  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
342  agreement.NotifyAckedMpdu (mpdu);
343 
344  // the current window must look like this:
345  //
346  // |0|0|0|0|0|0|1|1|1|1|0|0|0|0|0|0|
347  // ^
348  // |
349  // HEAD
350 
351  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after 1 unacknowledged MPDU");
352  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after 1 unacknowledged MPDU");
353  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), true, "Incorrect flag after 1 unacknowledged MPDU");
354  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), true, "Incorrect flag after 1 unacknowledged MPDU");
355  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after 1 unacknowledged MPDU");
356  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after 1 unacknowledged MPDU");
357  for (uint16_t i = 5; i < winSize; i++)
358  {
359  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after 1 unacknowledged MPDU");
360  }
361 
362  // the missing MPDU is now acknowledged; the window moves forward and the starting
363  // sequence number is the one of the first unacknowledged MPDU
364  mpdu->GetHeader ().SetSequenceNumber (startingSeq);
365  agreement.NotifyAckedMpdu (mpdu);
366 
367  // the current window must look like this:
368  //
369  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
370  // ^
371  // |
372  // HEAD
373 
374  startingSeq = (seqNumber + 1) % SEQNO_SPACE_SIZE;
375  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after acknowledgment of missing MPDU");
376  for (uint16_t i = 0; i < winSize; i++)
377  {
378  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Not all flags are cleared after acknowledgment of missing MPDU");
379  }
380 
381  // Now, create a hole of 3 MPDUs before 4 acknowledged MPDUs, another hole of 2 MPDUs before 3 acknowledged MPDUs
382  seqNumber = (seqNumber + 4) % SEQNO_SPACE_SIZE;
383  mpdu->GetHeader ().SetSequenceNumber (seqNumber);
384  agreement.NotifyAckedMpdu (mpdu);
385 
386  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
387  agreement.NotifyAckedMpdu (mpdu);
388 
389  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
390  agreement.NotifyAckedMpdu (mpdu);
391 
392  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
393  agreement.NotifyAckedMpdu (mpdu);
394 
395  seqNumber = (seqNumber + 3) % SEQNO_SPACE_SIZE;
396  mpdu->GetHeader ().SetSequenceNumber (seqNumber);
397  agreement.NotifyAckedMpdu (mpdu);
398 
399  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
400  agreement.NotifyAckedMpdu (mpdu);
401 
402  mpdu->GetHeader ().SetSequenceNumber (++seqNumber %= SEQNO_SPACE_SIZE);
403  agreement.NotifyAckedMpdu (mpdu);
404 
405  // the current window must look like this:
406  //
407  // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
408  // ^
409  // |
410  // HEAD
411 
412  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq, "Incorrect starting sequence after 3 unacknowledged MPDUs");
413  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after 3 unacknowledged MPDUs");
414  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), false, "Incorrect flag after 3 unacknowledged MPDUs");
415  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), false, "Incorrect flag after 3 unacknowledged MPDUs");
416  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after 3 unacknowledged MPDUs");
417  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after 3 unacknowledged MPDUs");
418  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (5), true, "Incorrect flag after 3 unacknowledged MPDUs");
419  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (6), true, "Incorrect flag after 3 unacknowledged MPDUs");
420  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (7), false, "Incorrect flag after 3 unacknowledged MPDUs");
421  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (8), false, "Incorrect flag after 3 unacknowledged MPDUs");
422  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (9), true, "Incorrect flag after 3 unacknowledged MPDUs");
423  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (10), true, "Incorrect flag after 3 unacknowledged MPDUs");
424  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (11), true, "Incorrect flag after 3 unacknowledged MPDUs");
425  for (uint16_t i = 12; i < winSize; i++)
426  {
427  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after 3 unacknowledged MPDUs");
428  }
429 
430  // the transmission of an MPDU beyond the current window (by 2 positions) is
431  // notified, hence the window moves forward 2 positions
432  seqNumber = (agreement.m_txWindow.GetWinEnd () + 2) % SEQNO_SPACE_SIZE;
433  mpdu->GetHeader ().SetSequenceNumber (seqNumber);
434  agreement.NotifyTransmittedMpdu (mpdu);
435 
436  // the current window must look like this:
437  //
438  // |1|0|0|1|1|1|0|0|0|0|0|0|0|1|1|1|
439  // ^
440  // |
441  // HEAD
442 
443  startingSeq = (startingSeq + 2) % SEQNO_SPACE_SIZE;
444  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
445  "Incorrect starting sequence after transmitting an MPDU beyond the current window");
446  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after transmitting an MPDU beyond the current window");
447  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), true, "Incorrect flag after transmitting an MPDU beyond the current window");
448  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), true, "Incorrect flag after transmitting an MPDU beyond the current window");
449  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after transmitting an MPDU beyond the current window");
450  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after transmitting an MPDU beyond the current window");
451  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (5), false, "Incorrect flag after transmitting an MPDU beyond the current window");
452  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (6), false, "Incorrect flag after transmitting an MPDU beyond the current window");
453  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (7), true, "Incorrect flag after transmitting an MPDU beyond the current window");
454  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (8), true, "Incorrect flag after transmitting an MPDU beyond the current window");
455  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (9), true, "Incorrect flag after transmitting an MPDU beyond the current window");
456  for (uint16_t i = 10; i < winSize; i++)
457  {
458  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after transmitting an MPDU beyond the current window");
459  }
460 
461  // another MPDU is transmitted beyond the current window. Now, the window advances
462  // until the first unacknowledged MPDU
463  seqNumber = (agreement.m_txWindow.GetWinEnd () + 1) % SEQNO_SPACE_SIZE;
464  mpdu->GetHeader ().SetSequenceNumber (seqNumber);
465  agreement.NotifyTransmittedMpdu (mpdu);
466 
467  // the current window must look like this:
468  //
469  // |0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|
470  // ^
471  // |
472  // HEAD
473 
474  startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
475  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
476  "Incorrect starting sequence after transmitting another MPDU beyond the current window");
477  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after transmitting another MPDU beyond the current window");
478  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (1), false, "Incorrect flag after transmitting another MPDU beyond the current window");
479  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (2), true, "Incorrect flag after transmitting another MPDU beyond the current window");
480  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (3), true, "Incorrect flag after transmitting another MPDU beyond the current window");
481  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (4), true, "Incorrect flag after transmitting another MPDU beyond the current window");
482  for (uint16_t i = 5; i < winSize; i++)
483  {
484  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after transmitting another MPDU beyond the current window");
485  }
486 
487  // the MPDU next to winStart is discarded, hence the window advances to make it an old packet.
488  // Since the subsequent MPDUs have been acknowledged, the window advances further.
489  seqNumber = (startingSeq + 1) % SEQNO_SPACE_SIZE;
490  mpdu->GetHeader ().SetSequenceNumber (seqNumber);
491  agreement.NotifyDiscardedMpdu (mpdu);
492 
493  // the current window must look like this:
494  //
495  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
496  // ^
497  // |
498  // HEAD
499 
500  startingSeq = (startingSeq + 5) % SEQNO_SPACE_SIZE;
501  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
502  "Incorrect starting sequence after discarding an MPDU");
503  for (uint16_t i = 0; i < winSize; i++)
504  {
505  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after discarding an MPDU");
506  }
507 
508  // Finally, check that the window correctly advances when the MPDU with the starting sequence number
509  // is acknowledged after being the only unacknowledged MPDU
510  for (uint16_t i = 1; i < winSize; i++)
511  {
512  mpdu->GetHeader ().SetSequenceNumber ((startingSeq + i) % SEQNO_SPACE_SIZE);
513  agreement.NotifyAckedMpdu (mpdu);
514  }
515 
516  // the current window must look like this:
517  //
518  // |1|1|1|1|1|1|0|1|1|1|1|1|1|1|1|1|
519  // ^
520  // |
521  // HEAD
522 
523  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
524  "Incorrect starting sequence after acknowledging all but the first MPDU");
525  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (0), false, "Incorrect flag after acknowledging all but the first MPDU");
526  for (uint16_t i = 1; i < winSize; i++)
527  {
528  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), true, "Incorrect flag after acknowledging all but the first MPDU");
529  }
530 
531  // acknowledge the first MPDU
532  mpdu->GetHeader ().SetSequenceNumber (startingSeq % SEQNO_SPACE_SIZE);
533  agreement.NotifyAckedMpdu (mpdu);
534 
535  // the current window must look like this:
536  //
537  // |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
538  // ^
539  // |
540  // HEAD
541 
542  startingSeq = (startingSeq + winSize) % SEQNO_SPACE_SIZE;
543  NS_TEST_EXPECT_MSG_EQ (agreement.GetStartingSequence (), startingSeq,
544  "Incorrect starting sequence after acknowledging the first MPDU");
545  for (uint16_t i = 0; i < winSize; i++)
546  {
547  NS_TEST_EXPECT_MSG_EQ (agreement.m_txWindow.At (i), false, "Incorrect flag after acknowledging the first MPDU");
548  }
549 }
550 
551 
559 {
560 public:
562 private:
563  virtual void DoRun ();
565 };
566 
568  : TestCase ("Check the correctness of block ack compressed bitmap")
569 {
570 }
571 
572 void
574 {
575  m_blockAckHdr.SetType (BlockAckType::COMPRESSED);
576 
577  //Case 1: startSeq < endSeq
578  // 179 242
580  for (uint16_t i = 179; i < 220; i++)
581  {
583  }
584  for (uint16_t i = 225; i <= 242; i++)
585  {
587  }
588  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
589  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
590  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0xff, "error in compressed bitmap");
591  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0xff, "error in compressed bitmap");
592  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0xff, "error in compressed bitmap");
593  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0xc1, "error in compressed bitmap");
594  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0xff, "error in compressed bitmap");
595  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0xff, "error in compressed bitmap");
597  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
598  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
599  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0xff, "error in compressed bitmap");
600  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0xff, "error in compressed bitmap");
601  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0xff, "error in compressed bitmap");
602  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0xc1, "error in compressed bitmap");
603  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0xff, "error in compressed bitmap");
604  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0xff, "error in compressed bitmap");
605  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (220), false, "error in compressed bitmap");
606  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (225), true, "error in compressed bitmap");
607  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (1500), false, "error in compressed bitmap");
608 
610 
611  //Case 2: startSeq > endSeq
612  // 4090 58
614  for (uint16_t i = 4090; i != 10; i = (i + 1) % 4096)
615  {
617  }
618  for (uint16_t i = 22; i < 25; i++)
619  {
621  }
622  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
623  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
624  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0x00, "error in compressed bitmap");
625  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0x70, "error in compressed bitmap");
626  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0x00, "error in compressed bitmap");
627  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0x00, "error in compressed bitmap");
628  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0x00, "error in compressed bitmap");
629  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0x00, "error in compressed bitmap");
631  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[0], 0xff, "error in compressed bitmap");
632  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[1], 0xff, "error in compressed bitmap");
633  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[2], 0x00, "error in compressed bitmap");
634  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[3], 0x70, "error in compressed bitmap");
635  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[4], 0x00, "error in compressed bitmap");
636  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[5], 0x00, "error in compressed bitmap");
637  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[6], 0x00, "error in compressed bitmap");
638  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetBitmap ()[7], 0x00, "error in compressed bitmap");
639  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (4090), true, "error in compressed bitmap");
640  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (4095), true, "error in compressed bitmap");
641  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (10), false, "error in compressed bitmap");
642  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (35), false, "error in compressed bitmap");
643  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (80), false, "error in compressed bitmap");
644 }
645 
646 
654 {
655 public:
660  BlockAckRecipientBufferTest (uint16_t ssn);
661  virtual ~BlockAckRecipientBufferTest ();
662 
663  virtual void DoRun (void);
664 
670  void ForwardUp (Ptr<WifiMacQueueItem> mpdu);
671 
672 private:
673  uint16_t m_ssn;
674  std::list<Ptr<WifiMacQueueItem>> m_fwup;
675 };
676 
678  : TestCase ("Test case for Block Ack recipient reordering buffer operations"),
679  m_ssn (ssn)
680 {
681 }
682 
684 {
685 }
686 
687 void
689 {
690  m_fwup.push_back (mpdu);
691 }
692 
693 void
695 {
696  Ptr<MacRxMiddle> rxMiddle = Create<MacRxMiddle> ();
698 
699  RecipientBlockAckAgreement agreement (Mac48Address::Allocate () /* originator */,
700  true /* amsduSupported */, 0 /* tid */, 10 /* bufferSize */,
701  0 /* timeout */, m_ssn, true /* htSupported */);
702  agreement.SetMacRxMiddle (rxMiddle);
703 
704  WifiMacHeader hdr;
706  hdr.SetAddr1 (Mac48Address::Allocate ());
707  hdr.SetQosTid (0);
708 
709  // Notify the reception of an MPDU with SN = SSN.
710  hdr.SetSequenceNumber (m_ssn);
711  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
712 
713  // This MPDU is forwarded up and WinStartB is set to SSN + 1.
714  NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 1, "MPDU with SN=SSN must have been forwarded up");
715  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (), m_ssn,
716  "The MPDU forwarded up is not the expected one");
717 
718  m_fwup.clear ();
719 
720  // Notify the reception of MPDUs with SN = SSN + {4, 2, 5, 3, 10, 7}
721  // Recipient buffer: | |X|X|X|X| |X| | |X|
722  // ^
723  // |
724  // SSN + 1
726  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
728  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
730  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
732  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
734  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
736  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
737 
738  // No MPDU is forwarded up because the one with SN = SSN + 1 is missing
739  NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
740 
741  // Notify the reception of an "old" MPDU (SN = SSN)
742  hdr.SetSequenceNumber (m_ssn);
743  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
744 
745  // No MPDU is forwarded up
746  NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
747 
748  // Notify the reception of a duplicate MPDU (SN = SSN + 2)
750  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(10), hdr));
751 
752  // No MPDU is forwarded up
753  NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
754 
755  // Notify the reception of an MPDU with SN = SSN + 1
756  // Recipient buffer: |X|X|X|X|X| |X| | |X|
757  // ^
758  // |
759  // SSN + 1
761  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
762 
763  // All the MPDUs with SN = SSN + {1, 2, 3, 4, 5} must have been forwarded up in order
764  NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 5, "5 MPDUs must have been forwarded up");
765 
766  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
767  (m_ssn + 1) % SEQNO_SPACE_SIZE,
768  "The MPDU forwarded up is not the expected one");
769  m_fwup.pop_front ();
770 
771  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
772  (m_ssn + 2) % SEQNO_SPACE_SIZE,
773  "The MPDU forwarded up is not the expected one");
774  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetPacketSize (), 0,
775  "The MPDU forwarded up is not the expected one");
776  m_fwup.pop_front ();
777 
778  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
779  (m_ssn + 3) % SEQNO_SPACE_SIZE,
780  "The MPDU forwarded up is not the expected one");
781  m_fwup.pop_front ();
782 
783  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
784  (m_ssn + 4) % SEQNO_SPACE_SIZE,
785  "The MPDU forwarded up is not the expected one");
786  m_fwup.pop_front ();
787 
788  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
789  (m_ssn + 5) % SEQNO_SPACE_SIZE,
790  "The MPDU forwarded up is not the expected one");
791  m_fwup.pop_front ();
792 
793  // Recipient buffer: | |X| | |X| | | | | |
794  // ^ ^
795  // | |
796  // SSN + 6 SSN + 15
797  // Notify the reception of an MPDU beyond the current window (SN = SSN + 17)
799  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
800 
801  // WinStartB is set to SSN + 8 (so that WinEndB = SSN + 17). The MPDU with
802  // SN = SSN + 7 is forwarded up, irrespective of the missed reception of the
803  // MPDU with SN = SSN + 6
804  NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 1, "One MPDU must have been forwarded up");
805 
806  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
807  (m_ssn + 7) % SEQNO_SPACE_SIZE,
808  "The MPDU forwarded up is not the expected one");
809  m_fwup.pop_front ();
810 
811  // Recipient buffer: | | |X| | | | | | |X|
812  // ^ ^
813  // | |
814  // SSN + 8 SSN + 17
815  // Notify the reception of a BlockAckReq with SSN = SSN + 7
816  agreement.NotifyReceivedBar ((m_ssn + 7) % SEQNO_SPACE_SIZE);
817 
818  // No MPDU is forwarded up
819  NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
820 
821  // Notify the reception of a BlockAckReq with SSN = SSN + 8
822  agreement.NotifyReceivedBar ((m_ssn + 8) % SEQNO_SPACE_SIZE);
823 
824  // No MPDU is forwarded up
825  NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
826 
827  // Notify the reception of MPDUs with SN = SSN + {9, 11}
828  // Recipient buffer: | |X|X|X| | | | | |X|
829  // ^ ^
830  // | |
831  // SSN + 8 SSN + 17
833  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
835  agreement.NotifyReceivedMpdu (Create<WifiMacQueueItem> (Create<Packet>(), hdr));
836 
837  // No MPDU is forwarded up because the one with SN = SSN + 8 is missing
838  NS_TEST_ASSERT_MSG_EQ (m_fwup.empty (), true, "No MPDU must have been forwarded up");
839 
840  // Notify the reception of a BlockAckReq with SSN = SSN + 10
841  agreement.NotifyReceivedBar ((m_ssn + 10) % SEQNO_SPACE_SIZE);
842 
843  // Forward up buffered MPDUs with SN < SSN + 10 (the MPDU with SN = SSN + 9)
844  // and then buffered MPDUs with SN >= SSN + 10 until a hole is found (MPDUs
845  // with SN = SSN + 10 and SN = SSN + 11)
846  NS_TEST_ASSERT_MSG_EQ (m_fwup.size (), 3, "3 MPDUs must have been forwarded up");
847 
848  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
849  (m_ssn + 9) % SEQNO_SPACE_SIZE,
850  "The MPDU forwarded up is not the expected one");
851  m_fwup.pop_front ();
852 
853  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
854  (m_ssn + 10) % SEQNO_SPACE_SIZE,
855  "The MPDU forwarded up is not the expected one");
856  m_fwup.pop_front ();
857 
858  NS_TEST_ASSERT_MSG_EQ (m_fwup.front ()->GetHeader ().GetSequenceNumber (),
859  (m_ssn + 11) % SEQNO_SPACE_SIZE,
860  "The MPDU forwarded up is not the expected one");
861  m_fwup.pop_front ();
862 
863  Simulator::Run ();
864  Simulator::Destroy ();
865 }
866 
867 
913 {
918  {
924  void Trace (Time startTime, Time duration);
926  };
927 
928 public:
935 
936  virtual void DoRun (void);
937 
938 
939 private:
940  bool m_txop;
941  uint32_t m_received;
942  uint16_t m_txTotal;
943  uint16_t m_txSinceBar;
944  uint16_t m_nBar;
946  uint16_t m_nBa;
947 
954  void L7Receive (std::string context, Ptr<const Packet> p, const Address &adr);
961  void Transmit (std::string context, Ptr<const Packet> p, double power);
968  void Receive (std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
969 };
970 
971 void
973 {
974  if (duration > m_max)
975  {
976  m_max = duration;
977  }
978 }
979 
981  : TestCase ("Test case for Block Ack Policy with aggregation disabled"),
982  m_txop (txop),
983  m_received (0),
984  m_txTotal (0),
985  m_txSinceBar (0),
986  m_nBar (0),
987  m_nBa (0)
988 {
989 }
990 
992 {
993 }
994 
995 void
997 {
998  if (p->GetSize () == 1400)
999  {
1000  m_received++;
1001  }
1002 }
1003 
1004 void
1005 BlockAckAggregationDisabledTest::Transmit (std::string context, Ptr<const Packet> p, double power)
1006 {
1007  WifiMacHeader hdr;
1008  p->PeekHeader (hdr);
1009 
1010  if (m_nBar < 2 && (m_txSinceBar == 9 || m_txTotal == 14))
1011  {
1012  NS_TEST_ASSERT_MSG_EQ (hdr.IsBlockAckReq (), true, "Didn't get a BlockAckReq when expected");
1013  }
1014  else
1015  {
1016  NS_TEST_ASSERT_MSG_EQ (hdr.IsBlockAckReq (), false, "Got a BlockAckReq when not expected");
1017  }
1018 
1019  if (hdr.IsQosData ())
1020  {
1021  m_txTotal++;
1022  if (hdr.IsQosBlockAck ())
1023  {
1024  m_txSinceBar++;
1025  }
1026 
1027  if (!m_txop)
1028  {
1029  NS_TEST_EXPECT_MSG_EQ ((m_txTotal == 1 || hdr.IsQosBlockAck ()), true, "Unexpected QoS ack policy");
1030  }
1031  else
1032  {
1033  NS_TEST_EXPECT_MSG_EQ ((m_txTotal <= 2 || hdr.IsQosBlockAck ()), true, "Unexpected QoS ack policy");
1034  }
1035  }
1036  else if (hdr.IsBlockAckReq ())
1037  {
1038  m_txSinceBar = 0;
1039  m_nBar++;
1040  }
1041 }
1042 
1043 void
1045 {
1046  WifiMacHeader hdr;
1047  p->PeekHeader (hdr);
1048 
1049  if (hdr.IsBlockAck ())
1050  {
1051  m_nBa++;
1052  }
1053 }
1054 
1055 void
1057 {
1058  NodeContainer wifiStaNode;
1059  wifiStaNode.Create (1);
1060 
1062  wifiApNode.Create (1);
1063 
1064  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
1066  phy.SetChannel (channel.Create ());
1067 
1068  WifiHelper wifi;
1069  wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
1070  Config::SetDefault ("ns3::WifiDefaultAckManager::BaThreshold", DoubleValue (0.125));
1071  wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
1072 
1074  Ssid ssid = Ssid ("ns-3-ssid");
1075  mac.SetType ("ns3::StaWifiMac",
1076  "BE_MaxAmsduSize", UintegerValue (0),
1077  "BE_MaxAmpduSize", UintegerValue (0),
1078  "Ssid", SsidValue (ssid),
1079  /* setting blockack threshold for sta's BE queue */
1080  "BE_BlockAckThreshold", UintegerValue (2),
1081  "ActiveProbing", BooleanValue (false));
1082 
1084  staDevices = wifi.Install (phy, mac, wifiStaNode);
1085 
1086  mac.SetType ("ns3::ApWifiMac",
1087  "BE_MaxAmsduSize", UintegerValue (0),
1088  "BE_MaxAmpduSize", UintegerValue (0),
1089  "Ssid", SsidValue (ssid),
1090  "BeaconGeneration", BooleanValue (true));
1091 
1093  apDevices = wifi.Install (phy, mac, wifiApNode);
1094 
1096  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1097 
1098  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
1099  positionAlloc->Add (Vector (1.0, 0.0, 0.0));
1100  mobility.SetPositionAllocator (positionAlloc);
1101 
1102  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1103  mobility.Install (wifiApNode);
1104  mobility.Install (wifiStaNode);
1105 
1106  Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice> (apDevices.Get (0));
1107  Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice> (staDevices.Get (0));
1108 
1109  // Disable A-MPDU aggregation
1110  sta_device->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0));
1111  TxopDurationTracer txopTracer;
1112 
1113  if (m_txop)
1114  {
1115  PointerValue ptr;
1116  sta_device->GetMac ()->GetAttribute ("BE_Txop", ptr);
1117  ptr.Get<QosTxop> ()->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &txopTracer));
1118 
1119  // set the TXOP limit on BE AC
1120  Ptr<RegularWifiMac> ap_mac = DynamicCast<RegularWifiMac> (ap_device->GetMac ());
1121  NS_ASSERT (ap_mac);
1122  ap_mac->GetAttribute ("BE_Txop", ptr);
1123  ptr.Get<QosTxop> ()->SetTxopLimit (MicroSeconds (4800));
1124  }
1125 
1126  PacketSocketAddress socket;
1127  socket.SetSingleDevice (sta_device->GetIfIndex ());
1128  socket.SetPhysicalAddress (ap_device->GetAddress ());
1129  socket.SetProtocol (1);
1130 
1131  // give packet socket powers to nodes.
1132  PacketSocketHelper packetSocket;
1133  packetSocket.Install (wifiStaNode);
1134  packetSocket.Install (wifiApNode);
1135 
1136  // the first client application generates a single packet, which is sent
1137  // with the normal ack policy because there are no other packets queued
1138  Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient> ();
1139  client1->SetAttribute ("PacketSize", UintegerValue (1400));
1140  client1->SetAttribute ("MaxPackets", UintegerValue (1));
1141  client1->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1142  client1->SetRemote (socket);
1143  wifiStaNode.Get (0)->AddApplication (client1);
1144  client1->SetStartTime (Seconds (1));
1145  client1->SetStopTime (Seconds (3.0));
1146 
1147  // the second client application generates 13 packets. Even if when the first
1148  // packet is queued the queue is empty, the first packet is not transmitted
1149  // immediately, but the EDCAF waits for the next slot boundary. At that time,
1150  // other packets have been queued, hence a BA agreement is established first.
1151  Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient> ();
1152  client2->SetAttribute ("PacketSize", UintegerValue (1400));
1153  client2->SetAttribute ("MaxPackets", UintegerValue (13));
1154  client2->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1155  client2->SetRemote (socket);
1156  wifiStaNode.Get (0)->AddApplication (client2);
1157  client2->SetStartTime (Seconds (1.5));
1158  client2->SetStopTime (Seconds (3.0));
1159 
1160  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
1161  server->SetLocal (socket);
1162  wifiApNode.Get (0)->AddApplication (server);
1163  server->SetStartTime (Seconds (0.0));
1164  server->SetStopTime (Seconds (4.0));
1165 
1166  Config::Connect ("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx", MakeCallback (&BlockAckAggregationDisabledTest::L7Receive, this));
1167  Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyTxBegin", MakeCallback (&BlockAckAggregationDisabledTest::Transmit, this));
1168  Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyRxBegin", MakeCallback (&BlockAckAggregationDisabledTest::Receive, this));
1169 
1170  Simulator::Stop (Seconds (5));
1171  Simulator::Run ();
1172 
1173  Simulator::Destroy ();
1174 
1175  // The client applications generate 14 packets, so we expect that the wifi PHY
1176  // layer transmits 14 MPDUs, the server application receives 14 packets, and
1177  // two BARs are transmitted.
1178  NS_TEST_EXPECT_MSG_EQ (m_txTotal, 14, "Unexpected number of transmitted packets");
1179  NS_TEST_EXPECT_MSG_EQ (m_received, 14, "Unexpected number of received packets");
1180  NS_TEST_EXPECT_MSG_EQ (m_nBar, 2, "Unexpected number of Block Ack Requests");
1181  NS_TEST_EXPECT_MSG_EQ (m_nBa, 2, "Unexpected number of Block Ack Responses");
1182  if (m_txop)
1183  {
1184  NS_TEST_EXPECT_MSG_LT (txopTracer.m_max, MicroSeconds (4800), "TXOP duration exceeded!");
1185  NS_TEST_EXPECT_MSG_GT (txopTracer.m_max, MicroSeconds (3008), "The maximum TXOP duration is too short!");
1186  }
1187 }
1188 
1196 {
1197 public:
1198  BlockAckTestSuite ();
1199 };
1200 
1202  : TestSuite ("wifi-block-ack", UNIT)
1203 {
1204  AddTestCase (new PacketBufferingCaseA, TestCase::QUICK);
1205  AddTestCase (new PacketBufferingCaseB, TestCase::QUICK);
1206  AddTestCase (new OriginatorBlockAckWindowTest, TestCase::QUICK);
1207  AddTestCase (new CtrlBAckResponseHeaderTest, TestCase::QUICK);
1208  AddTestCase (new BlockAckRecipientBufferTest (0), TestCase::QUICK);
1209  AddTestCase (new BlockAckRecipientBufferTest (4090), TestCase::QUICK);
1210  AddTestCase (new BlockAckAggregationDisabledTest (false), TestCase::QUICK);
1211  AddTestCase (new BlockAckAggregationDisabledTest (true), TestCase::QUICK);
1212 }
1213 
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
std::list< uint16_t > m_expectedBuffer
expected test buffer
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Test for recipient reordering buffer operations.
Ptr< T > Get(void) const
Definition: pointer.h:201
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
Maintains the state and information about transmitted MPDUs with Ack Policy set to Block Ack for an o...
void Trace(Time startTime, Time duration)
Callback for the TxopTrace trace.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Make it easy to create and manage PHY objects for the YANS model.
void SetForwardCallback(ForwardUpCallback callback)
Set a callback to forward the packet up.
A suite of tests to run.
Definition: test.h:1343
Maintains the scoreboard and the receive reordering buffer used by a recipient of a Block Ack agreeme...
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
uint32_t m_received
received packets
an address for a packet socket
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:283
staDevices
Definition: third.py:103
void Transmit(std::string context, Ptr< const Packet > p, double power)
Callback invoked when PHY transmits a packet.
encapsulates test code
Definition: test.h:1153
Keeps the maximum duration among all TXOPs.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:326
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
BlockAckWindow m_txWindow
originator&#39;s transmit window
CtrlBAckResponseHeader m_blockAckHdr
block ack header
Give ns3::PacketSocket powers to ns3::Node.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
uint16_t m_nBar
transmitted BlockAckReq frames
Address GetAddress(void) const
void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
a polymophic address class
Definition: address.h:90
bool IsBlockAck(void) const
Return true if the header is a BlockAck header.
virtual void DoRun(void)
Implementation to actually run this TestCase.
channel
Definition: third.py:92
void NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Advance the transmit window beyond the MPDU that has been reported to be discarded.
mobility
Definition: third.py:108
phy
Definition: third.py:93
uint16_t GetWinStart(void) const
Get the current winStart value.
bool IsBlockAckReq(void) const
Return true if the header is a BlockAckRequest header.
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
AttributeValue implementation for Time.
Definition: nstime.h:1353
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Hold an unsigned integer type.
Definition: uinteger.h:44
double startTime
ssid
Definition: third.py:100
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
holds a vector of ns3::NetDevice pointers
mac
Definition: third.py:99
bool IsPacketReceived(uint16_t seq) const
Check if the packet with the given sequence number was acknowledged in this BlockAck response...
uint16_t m_txTotal
transmitted data packets
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
const std::vector< uint8_t > & GetBitmap(void) const
Return a const reference to the bitmap from the BlockAck response header.
Headers for BlockAck response.
Definition: ctrl-headers.h:199
void Receive(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback invoked when PHY receives a packet.
wifiApNode
Definition: third.py:90
Test for the originator block ack window.
void ForwardUp(Ptr< WifiMacQueueItem > mpdu)
Keep track of MPDUs that are forwarded up.
uint16_t m_nBa
received BlockAck frames
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
Packet Buffering Case B.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
std::vector< bool >::reference At(std::size_t distance)
Get a reference to the element in the window having the given distance from the current winStart...
void NotifyAckedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that the given MPDU has been acknowledged and advance the transmit window if possible...
void NotifyTransmittedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Advance the transmit window so as to include the transmitted MPDU, if the latter is not an old packet...
virtual void DoRun(void)
Implementation to actually run this TestCase.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
keep track of a set of node pointers.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void NotifyReceivedBar(uint16_t startingSequenceNumber)
Update both the scoreboard and the receive reordering buffer upon reception of a Block Ack Request...
void SetType(BlockAckType type)
Set the block ack type.
an EUI-48 address
Definition: mac48-address.h:43
Test for Block Ack Policy with aggregation disabled.
std::list< Ptr< WifiMacQueueItem > > m_fwup
list of MPDUs that have been forwarded up
manage and create wifi channel objects for the YANS model.
void NotifyReceivedMpdu(Ptr< WifiMacQueueItem > mpdu)
Update both the scoreboard and the receive reordering buffer upon reception of the given MPDU...
create MAC layers for a ns3::WifiNetDevice.
void ResetBitmap(void)
Reset the bitmap to 0.
BlockAckAggregationDisabledTest(bool txop)
Constructor.
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition: test.h:1088
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
wifi
Definition: third.py:96
Helper class used to assign positions and mobility models to nodes.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
bool IsQosBlockAck(void) const
Return if the QoS Ack policy is Block Ack.
void SetReceivedPacket(uint16_t seq)
Set the bitmap that the packet with the given sequence number was received.
Packet Buffering Case A.
Ptr< WifiMac > GetMac(void) const
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
uint16_t GetWinEnd(void) const
Get the current winEnd value.
virtual void DoRun()
Implementation to actually run this TestCase.
std::size_t GetWinSize(void) const
Get the window size.
void SetRemote(PacketSocketAddress addr)
set the remote address and protocol to be used
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
Definition: qos-utils.cc:94
virtual void DoRun()
Implementation to actually run this TestCase.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
AttributeValue implementation for Ssid.
Definition: ssid.h:105
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
uint16_t m_ssn
the Starting Sequence Number used to initialize WinStartB
void SetProtocol(uint16_t protocol)
Set the protocol.
void Add(Vector v)
Add a position to the list of positions.
Block Ack Test Suite.
bool m_txop
true for non-null TXOP limit
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:901
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
const uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
Definition: wifi-utils.h:222
void L7Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Function to trace packets received by the server application.
apDevices
Definition: third.py:106
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data...
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Test for block ack header.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
uint16_t GetStartingSequence(void) const
Return the starting sequence number of the transmit window, if a transmit window has been initialized...
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint16_t m_txSinceBar
packets transmitted since the agreement was established or the last block ack was received ...
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
static BlockAckTestSuite g_blockAckTestSuite
the test suite
std::list< uint16_t > m_expectedBuffer
expected test buffer
BlockAckRecipientBufferTest(uint16_t ssn)
Constructor.
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
void InitTxWindow(void)
Initialize the originator&#39;s transmit window by setting its size and starting sequence number equal to...
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
Implements the IEEE 802.11 MAC header.