A Discrete-Event Network Simulator
API
dcf-manager-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/test.h"
22 #include "ns3/simulator.h"
23 #include "ns3/dcf-state.h"
24 #include "ns3/dcf-manager.h"
25 #include "ns3/dca-txop.h"
26 
27 using namespace ns3;
28 
29 class DcfManagerTest;
30 
37 class DcfStateTest : public DcfState
38 {
39 public:
51  void QueueTx (uint64_t txTime, uint64_t expectedGrantTime);
52 
53 
54 private:
56  friend class DcfManagerTest;
57 
58  typedef std::pair<uint64_t,uint64_t> ExpectedGrant;
59  typedef std::list<ExpectedGrant> ExpectedGrants;
60  struct ExpectedCollision
62  {
63  uint64_t at;
64  uint32_t nSlots;
65  };
66  typedef std::list<struct ExpectedCollision> ExpectedCollisions;
67 
68  ExpectedCollisions m_expectedInternalCollision;
69  ExpectedCollisions m_expectedCollision;
70  ExpectedGrants m_expectedGrants;
71 };
72 
73 
80 class DcaTxopTest : public DcaTxop
81 {
82 public:
89  DcaTxopTest (DcfManagerTest *test, uint32_t i);
90 
91 
92 private:
93  void NotifyAccessGranted (void);
94  void NotifyInternalCollision (void);
95  void NotifyCollision (void);
96  void NotifyChannelSwitching (void);
97  void NotifySleep (void);
98  void NotifyWakeUp (void);
99  void DoDispose (void);
100 
102  uint32_t m_i;
103 };
104 
105 
112 class DcfManagerTest : public TestCase
113 {
114 public:
115  DcfManagerTest ();
116  virtual void DoRun (void);
117 
122  void NotifyAccessGranted (uint32_t i);
127  void NotifyInternalCollision (uint32_t i);
132  void NotifyCollision (uint32_t i);
137  void NotifyChannelSwitching (uint32_t i);
138 
139 
140 private:
148  void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
153  void AddDcfState (uint32_t aifsn);
155  void EndTest (void);
162  void ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from);
169  void ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from);
175  void AddRxOkEvt (uint64_t at, uint64_t duration);
181  void AddRxErrorEvt (uint64_t at, uint64_t duration);
187  void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
193  void AddTxEvt (uint64_t at, uint64_t duration);
199  void AddNavReset (uint64_t at, uint64_t duration);
205  void AddNavStart (uint64_t at, uint64_t duration);
210  void AddAckTimeoutReset (uint64_t at);
218  void AddAccessRequest (uint64_t at, uint64_t txTime,
219  uint64_t expectedGrantTime, uint32_t from);
227  void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
228  uint64_t expectedGrantTime, uint32_t from);
237  void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
238  uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
245  void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, Ptr<DcfStateTest> state);
251  void AddCcaBusyEvt (uint64_t at, uint64_t duration);
257  void AddSwitchingEvt (uint64_t at, uint64_t duration);
263  void AddRxStartEvt (uint64_t at, uint64_t duration);
264 
265  typedef std::vector<Ptr<DcfStateTest> > DcfStates;
266  typedef std::vector<Ptr<DcaTxopTest> > Dca;
267 
269  DcfStates m_dcfStates;
270  Dca m_dca;
271  uint32_t m_ackTimeoutValue;
272 };
273 
275  : DcfState (dca)
276 {
277 }
278 
279 void
280 DcfStateTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime)
281 {
282  m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
283 }
284 
286  : m_test (test),
287  m_i (i)
288 {
289 }
290 
291 void
293 {
294  m_test = 0;
295  DcaTxop::DoDispose ();
296 }
297 
298 void
300 {
302 }
303 
304 void
306 {
308 }
309 
310 void
312 {
314 }
315 
316 void
318 {
320 }
321 
322 void
324 {
325 }
326 
327 void
329 {
330 }
331 
333  : TestCase ("DcfManager")
334 {
335 }
336 
337 void
339 {
340  Ptr<DcfStateTest> state = m_dcfStates[i];
341  NS_TEST_EXPECT_MSG_EQ (state->m_expectedGrants.empty (), false, "Have expected grants");
342  if (!state->m_expectedGrants.empty ())
343  {
344  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
345  state->m_expectedGrants.pop_front ();
346  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected access grant is now");
347  m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.first));
349  }
350 }
351 
352 void
353 DcfManagerTest::AddTxEvt (uint64_t at, uint64_t duration)
354 {
355  Simulator::Schedule (MicroSeconds (at) - Now (),
356  &DcfManager::NotifyTxStartNow, m_dcfManager,
357  MicroSeconds (duration));
358 }
359 
360 void
362 {
363  Ptr<DcfStateTest> state = m_dcfStates[i];
364  NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (), false, "Have expected internal collisions");
365  if (!state->m_expectedInternalCollision.empty ())
366  {
367  struct DcfStateTest::ExpectedCollision expected = state->m_expectedInternalCollision.front ();
368  state->m_expectedInternalCollision.pop_front ();
369  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected internal collision time is now");
370  state->StartBackoffNow (expected.nSlots);
371  }
372 }
373 
374 void
376 {
377  Ptr<DcfStateTest> state = m_dcfStates[i];
378  NS_TEST_EXPECT_MSG_EQ (state->m_expectedCollision.empty (), false, "Have expected collisions");
379  if (!state->m_expectedCollision.empty ())
380  {
381  struct DcfStateTest::ExpectedCollision expected = state->m_expectedCollision.front ();
382  state->m_expectedCollision.pop_front ();
383  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected collision is now");
384  state->StartBackoffNow (expected.nSlots);
385  }
386 }
387 
388 void
390 {
391  Ptr<DcfStateTest> state = m_dcfStates[i];
392  if (!state->m_expectedGrants.empty ())
393  {
394  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
395  state->m_expectedGrants.pop_front ();
396  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected grant is now");
397  }
398 }
399 
400 void
401 DcfManagerTest::ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from)
402 {
403  Ptr<DcfStateTest> state = m_dcfStates[from];
405  col.at = time;
406  col.nSlots = nSlots;
407  state->m_expectedInternalCollision.push_back (col);
408 }
409 
410 void
411 DcfManagerTest::ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from)
412 {
413  Ptr<DcfStateTest> state = m_dcfStates[from];
415  col.at = time;
416  col.nSlots = nSlots;
417  state->m_expectedCollision.push_back (col);
418 }
419 
420 void
421 DcfManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue)
422 {
423  m_dcfManager = CreateObject<DcfManager> ();
424  m_dcfManager->SetSlot (MicroSeconds (slotTime));
426  m_dcfManager->SetEifsNoDifs (MicroSeconds (eifsNoDifsNoSifs + sifs));
427  m_ackTimeoutValue = ackTimeoutValue;
428 }
429 
430 void
432 {
433  Ptr<DcaTxopTest> dca = CreateObject<DcaTxopTest> (this, m_dcfStates.size ());
434  m_dca.push_back (dca);
435  Ptr<DcfStateTest> state = CreateObject<DcfStateTest> (dca);
436  state->SetAifsn (aifsn);
437  m_dcfStates.push_back (state);
438  m_dcfManager->Add (state);
439 }
440 
441 void
443 {
444  Simulator::Run ();
445  Simulator::Destroy ();
446 
447  for (DcfStates::const_iterator i = m_dcfStates.begin (); i != m_dcfStates.end (); i++)
448  {
449  Ptr<DcfStateTest> state = *i;
450  NS_TEST_EXPECT_MSG_EQ (state->m_expectedGrants.empty (), true, "Have no expected grants");
451  NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (), true, "Have no internal collisions");
452  NS_TEST_EXPECT_MSG_EQ (state->m_expectedCollision.empty (), true, "Have no expected collisions");
453  state = 0;
454  }
455  m_dcfStates.clear ();
456 
457  for (Dca::const_iterator i = m_dca.begin (); i != m_dca.end (); i++)
458  {
459  Ptr<DcaTxopTest> dca = *i;
460  dca->Dispose ();
461  dca = 0;
462  }
463  m_dca.clear ();
464 
465  m_dcfManager = 0;
466 }
467 
468 void
469 DcfManagerTest::AddRxOkEvt (uint64_t at, uint64_t duration)
470 {
471  Simulator::Schedule (MicroSeconds (at) - Now (),
472  &DcfManager::NotifyRxStartNow, m_dcfManager,
473  MicroSeconds (duration));
474  Simulator::Schedule (MicroSeconds (at + duration) - Now (),
475  &DcfManager::NotifyRxEndOkNow, m_dcfManager);
476 }
477 
478 void
479 DcfManagerTest::AddRxInsideSifsEvt (uint64_t at, uint64_t duration)
480 {
481  Simulator::Schedule (MicroSeconds (at) - Now (),
482  &DcfManager::NotifyRxStartNow, m_dcfManager,
483  MicroSeconds (duration));
484 }
485 
486 void
487 DcfManagerTest::AddRxErrorEvt (uint64_t at, uint64_t duration)
488 {
489  Simulator::Schedule (MicroSeconds (at) - Now (),
490  &DcfManager::NotifyRxStartNow, m_dcfManager,
491  MicroSeconds (duration));
492  Simulator::Schedule (MicroSeconds (at + duration) - Now (),
493  &DcfManager::NotifyRxEndErrorNow, m_dcfManager);
494 }
495 
496 void
497 DcfManagerTest::AddNavReset (uint64_t at, uint64_t duration)
498 {
499  Simulator::Schedule (MicroSeconds (at) - Now (),
500  &DcfManager::NotifyNavResetNow, m_dcfManager,
501  MicroSeconds (duration));
502 }
503 
504 void
505 DcfManagerTest::AddNavStart (uint64_t at, uint64_t duration)
506 {
507  Simulator::Schedule (MicroSeconds (at) - Now (),
508  &DcfManager::NotifyNavStartNow, m_dcfManager,
509  MicroSeconds (duration));
510 }
511 
512 void
514 {
515  Simulator::Schedule (MicroSeconds (at) - Now (),
516  &DcfManager::NotifyAckTimeoutResetNow, m_dcfManager);
517 }
518 
519 void
520 DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime,
521  uint64_t expectedGrantTime, uint32_t from)
522 {
523  AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
524 }
525 
526 void
528  uint64_t expectedGrantTime, uint32_t from)
529 {
530  Simulator::Schedule (MicroSeconds (at) - Now (),
532  txTime, expectedGrantTime, m_dcfStates[from]);
533 }
534 
535 void
537  uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
538 {
539  NS_ASSERT (ackDelay < m_ackTimeoutValue);
540  Simulator::Schedule (MicroSeconds (at) - Now (),
542  txTime, expectedGrantTime, m_dcfStates[from]);
543  AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
544 }
545 
546 void
547 DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, Ptr<DcfStateTest> state)
548 {
549  state->QueueTx (txTime, expectedGrantTime);
550  m_dcfManager->RequestAccess (state);
551 }
552 
553 void
554 DcfManagerTest::AddCcaBusyEvt (uint64_t at, uint64_t duration)
555 {
556  Simulator::Schedule (MicroSeconds (at) - Now (),
557  &DcfManager::NotifyMaybeCcaBusyStartNow, m_dcfManager,
558  MicroSeconds (duration));
559 }
560 
561 void
562 DcfManagerTest::AddSwitchingEvt (uint64_t at, uint64_t duration)
563 {
564  Simulator::Schedule (MicroSeconds (at) - Now (),
565  &DcfManager::NotifySwitchingStartNow, m_dcfManager,
566  MicroSeconds (duration));
567 }
568 
569 void
570 DcfManagerTest::AddRxStartEvt (uint64_t at, uint64_t duration)
571 {
572  Simulator::Schedule (MicroSeconds (at) - Now (),
573  &DcfManager::NotifyRxStartNow, m_dcfManager,
574  MicroSeconds (duration));
575 }
576 
577 void
579 {
580  // Bug 2369 addresses this case
581  // 0 3 4 5 8 9 10 12
582  // | sifs | aifsn | tx | sifs | aifsn | | tx |
583  //
584  StartTest (1, 3, 10);
585  AddDcfState (1);
586  AddAccessRequest (1, 1, 4, 0);
587  // Generate backoff when the request is within SIFS
588  ExpectCollision (1, 0, 0); // 0 slots
589  AddAccessRequest (10, 2, 10, 0);
590  EndTest ();
591  // Bug 2369 addresses this case
592  // 0 3 5 6 9 11 12 13
593  // | sifs | aifsn | tx | sifs | aifsn | | tx |
594  //
595  StartTest (1, 3, 10);
596  AddDcfState (2);
597  AddAccessRequest (4, 1, 5, 0);
598  // Generate backoff when the request is within AIFSN
599  ExpectCollision (4, 0, 0); // 0 slots
600  AddAccessRequest (12, 2, 12, 0);
601  EndTest ();
602  // Check that receiving inside SIFS shall be cancelled properly:
603  // 0 3 4 5 8 9 12 13 14
604  // | sifs | aifsn | tx | sifs | ack | sifs | aifsn | |tx |
605  //
606 
607  StartTest (1, 3, 10);
608  AddDcfState (1);
609  AddAccessRequest (1, 1, 4, 0);
610  ExpectCollision (1, 0, 0);
611  AddRxInsideSifsEvt (6, 10);
612  AddTxEvt (8, 1);
613  AddAccessRequest (14, 2, 14, 0);
614  EndTest ();
615  // The test below mainly intends to test the case where the medium
616  // becomes busy in the middle of a backoff slot: the backoff counter
617  // must not be decremented for this backoff slot. This is the case
618  // below for the backoff slot starting at time 78us.
619  //
620  // 20 60 66 70 74 78 80 100 106 110 114 118 120
621  // | rx | sifs | aifsn | bslot0 | bslot1 | | rx | sifs | aifsn | bslot2 | bslot3 | tx |
622  // |
623  // 30 request access. backoff slots: 4
624 
625  StartTest (4, 6, 10);
626  AddDcfState (1);
627  AddRxOkEvt (20, 40);
628  AddRxOkEvt (80, 20);
629  AddAccessRequest (30, 2, 118, 0);
630  ExpectCollision (30, 4, 0); //backoff: 4 slots
631  EndTest ();
632  // Test the case where the backoff slots is zero.
633  //
634  // 20 60 66 70 72
635  // | rx | sifs | aifsn | tx |
636  // |
637  // 30 request access. backoff slots: 0
638 
639  StartTest (4, 6, 10);
640  AddDcfState (1);
641  AddRxOkEvt (20, 40);
642  AddAccessRequest (30, 2, 70, 0);
643  ExpectCollision (30, 0, 0); // backoff: 0 slots
644  EndTest ();
645  // Test shows when two frames are received without interval between
646  // them:
647  // 20 60 100 106 110 112
648  // | rx | rx |sifs | aifsn | tx |
649  // |
650  // 30 request access. backoff slots: 0
651 
652  StartTest (4, 6, 10);
653  AddDcfState (1);
654  AddRxOkEvt (20, 40);
655  AddRxOkEvt (60, 40);
656  AddAccessRequest (30, 2, 110, 0);
657  ExpectCollision (30, 0, 0); //backoff: 0 slots
658  EndTest ();
659 
660  // Bug 2369. Test case of requesting access within SIFS interval
661  //
662  // 20 60 66 70 74
663  // | rx | sifs | aifsn | backoff | tx |
664  // |
665  // 62 request access.
666  //
667  StartTest (4, 6, 10);
668  AddDcfState (1);
669  AddRxOkEvt (20, 40);
670  AddAccessRequest (62, 2, 74, 0);
671  ExpectCollision (62, 1, 0); //backoff: 1 slots
672  EndTest ();
673 
674  // Bug 2369. Test case of requesting access after DIFS (no backoff)
675  //
676  // 20 60 66 70
677  // | rx | sifs | aifsn | tx |
678  // |
679  // 70 request access.
680  //
681  StartTest (4, 6, 10);
682  AddDcfState (1);
683  AddRxOkEvt (20, 40);
684  AddAccessRequest (70, 2, 70, 0);
685  EndTest ();
686 
687  // Test an EIFS
688  //
689  // 20 60 66 76 86 90 94 98 102 106
690  // | rx | sifs | acktxttime | sifs + aifsn | bslot0 | bslot1 | bslot2 | bslot3 | tx |
691  // | | <------eifs------>|
692  // 30 request access. backoff slots: 4
693  StartTest (4, 6, 10);
694  AddDcfState (1);
695  AddRxErrorEvt (20, 40);
696  AddAccessRequest (30, 2, 102, 0);
697  ExpectCollision (30, 4, 0); //backoff: 4 slots
698  EndTest ();
699 
700  // Test an EIFS which is interupted by a successfull transmission.
701  //
702  // 20 60 66 69 75 81 85 89 93 97 101 103
703  // | rx | sifs | | rx | sifs | aifsn | bslot0 | bslot1 | bslot2 | bslot3 | tx |
704  // | | <--eifs-->|
705  // 30 request access. backoff slots: 4
706  StartTest (4, 6, 10);
707  AddDcfState (1);
708  AddRxErrorEvt (20, 40);
709  AddAccessRequest (30, 2, 101, 0);
710  ExpectCollision (30, 4, 0); //backoff: 4 slots
711  AddRxOkEvt (69, 6);
712  EndTest ();
713 
714  // Test two DCFs which suffer an internal collision. the first DCF has a higher
715  // priority than the second DCF.
716  //
717  // 20 60 66 70 74 78 88
718  // DCF0 | rx | sifs | aifsn | bslot0 | bslot1 | tx |
719  // DCF1 | rx | sifs | aifsn | aifsn | aifsn | | sifs | aifsn | aifsn | aifsn | bslot | tx |
720  // 94 98 102 106 110 112
721  StartTest (4, 6, 10);
722  AddDcfState (1); //high priority DCF
723  AddDcfState (3); //low priority DCF
724  AddRxOkEvt (20, 40);
725  AddAccessRequest (30, 10, 78, 0);
726  ExpectCollision (30, 2, 0); //backoff: 2 slot
727  AddAccessRequest (40, 2, 110, 1);
728  ExpectCollision (40, 0, 1); //backoff: 0 slot
729  ExpectInternalCollision (78, 1, 1); //backoff: 1 slot
730  EndTest ();
731 
732  // Test of AckTimeout handling: First queue requests access and ack procedure fails,
733  // inside the ack timeout second queue with higher priority requests access.
734  //
735  // 20 40 50 60 66 76
736  // DCF0 - low | tx | ack timeout |sifs| |
737  // DCF1 - high | | |sifs| tx |
738  // ^ request access
739  StartTest (4, 6, 10);
740  AddDcfState (2); //high priority DCF
741  AddDcfState (0); //low priority DCF
742  AddAccessRequestWithAckTimeout (20, 20, 20, 0);
743  AddAccessRequest (50, 10, 66, 1);
744  ExpectCollision (50, 0, 1);
745  EndTest ();
746 
747  // Test of AckTimeout handling:
748  //
749  // First queue requests access and ack is 2 us delayed (got ack interval at the picture),
750  // inside this interval second queue with higher priority requests access.
751  //
752  // 20 40 41 42 48 58
753  // DCF0 - low | tx |got ack |sifs| |
754  // DCF1 - high | | |sifs| tx |
755  // ^ request access
756  StartTest (4, 6, 10);
757  AddDcfState (2); //high priority DCF
758  AddDcfState (0); //low priority DCF
759  AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
760  AddAccessRequest (41, 10, 48, 1);
761  ExpectCollision (41, 0, 1);
762  EndTest ();
763 
764  //Repeat the same but with one queue:
765  // 20 40 41 42 48 58
766  // DCF0 - low | tx |got ack |sifs| |
767  // ^ request access
768  StartTest (4, 6, 10);
769  AddDcfState (2);
770  AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
771  AddAccessRequest (41, 10, 56, 0);
772  ExpectCollision (41, 0, 0);
773  EndTest ();
774 
775  // test simple NAV count. This scenario modelizes a simple DATA+ACK handshake
776  // where the data rate used for the ACK is higher than expected by the DATA source
777  // so, the data exchange completes before the end of nav.
778  StartTest (4, 6, 10);
779  AddDcfState (1);
780  AddRxOkEvt (20, 40);
781  AddNavStart (60, 15);
782  AddRxOkEvt (66, 5);
783  AddNavStart (71, 0);
784  AddAccessRequest (30, 10, 93, 0);
785  ExpectCollision (30, 2, 0); //backoff: 2 slot
786  EndTest ();
787 
788  // test more complex NAV handling by a CF-poll. This scenario modelizes a
789  // simple DATA+ACK handshake interrupted by a CF-poll which resets the
790  // NAV counter.
791  StartTest (4, 6, 10);
792  AddDcfState (1);
793  AddRxOkEvt (20, 40);
794  AddNavStart (60, 15);
795  AddRxOkEvt (66, 5);
796  AddNavReset (71, 2);
797  AddAccessRequest (30, 10, 91, 0);
798  ExpectCollision (30, 2, 0); //backoff: 2 slot
799  EndTest ();
800 
801 
802  StartTest (4, 6, 10);
803  AddDcfState (2);
804  AddRxOkEvt (20, 40);
805  AddAccessRequest (80, 10, 80, 0);
806  EndTest ();
807 
808 
809  StartTest (4, 6, 10);
810  AddDcfState (2);
811  AddRxOkEvt (20, 40);
812  AddRxOkEvt (78, 8);
813  AddAccessRequest (30, 50, 108, 0);
814  ExpectCollision (30, 3, 0); //backoff: 3 slots
815  EndTest ();
816 
817 
818  // Channel switching tests
819 
820  // 0 20 23 24 25
821  // | switching | sifs | aifsn | tx |
822  // |
823  // 21 access request.
824  StartTest (1, 3, 10);
825  AddDcfState (1);
826  AddSwitchingEvt (0,20);
827  AddAccessRequest (21, 1, 24, 0);
828  ExpectCollision (21, 0, 0);
829  EndTest ();
830 
831  // 20 40 50 53 54 55 56 57
832  // | switching | busy | sifs | aifsn | bslot0 | bslot 1 | tx |
833  // | |
834  // 30 busy. 45 access request.
835  //
836  StartTest (1, 3, 10);
837  AddDcfState (1);
838  AddSwitchingEvt (20,20);
839  AddCcaBusyEvt (30,20);
840  ExpectCollision (45, 2, 0); //backoff: 2 slots
841  AddAccessRequest (45, 1, 56, 0);
842  EndTest ();
843 
844  // 20 30 50 53 54 55
845  // | rx | switching | sifs | aifsn | tx |
846  // |
847  // 51 access request.
848  //
849  StartTest (1, 3, 10);
850  AddDcfState (1);
851  AddRxStartEvt (20,40);
852  AddSwitchingEvt (30,20);
853  AddAccessRequest (51, 1, 54, 0);
854  ExpectCollision (51, 0, 0);
855  EndTest ();
856 
857  // 20 30 50 53 54 55
858  // | busy | switching | sifs | aifsn | tx |
859  // |
860  // 51 access request.
861  //
862  StartTest (1, 3, 10);
863  AddDcfState (1);
864  AddCcaBusyEvt (20,40);
865  AddSwitchingEvt (30,20);
866  AddAccessRequest (51, 1, 54, 0);
867  ExpectCollision (51, 0, 0);
868  EndTest ();
869 
870  // 20 30 50 53 54 55
871  // | nav | switching | sifs | aifsn | tx |
872  // |
873  // 51 access request.
874  //
875  StartTest (1, 3, 10);
876  AddDcfState (1);
877  AddNavStart (20,40);
878  AddSwitchingEvt (30,20);
879  AddAccessRequest (51, 1, 54, 0);
880  ExpectCollision (51, 0, 0);
881  EndTest ();
882 
883  // 20 40 50 55 58 59 60
884  // | tx | ack timeout | switching | sifs | aifsn | tx |
885  // | |
886  // 45 access request. 56 access request.
887  //
888  StartTest (1, 3, 10);
889  AddDcfState (1);
890  AddAccessRequestWithAckTimeout (20, 20, 20, 0);
891  AddAccessRequest (45, 1, 50, 0);
892  ExpectCollision (45, 0, 0);
893  AddSwitchingEvt (50,5);
894  AddAccessRequest (56, 1, 59, 0);
895  ExpectCollision (56, 0, 0);
896  EndTest ();
897 
898  // 20 60 66 70 74 78 80 100 106 110 112
899  // | rx | sifs | aifsn | bslot0 | bslot1 | | switching | sifs | aifsn | tx |
900  // | |
901  // 30 access request. 101 access request.
902  //
903  StartTest (4, 6, 10);
904  AddDcfState (1);
905  AddRxOkEvt (20,40);
906  AddAccessRequest (30, 2, 80, 0);
907  ExpectCollision (30, 4, 0); //backoff: 4 slots
908  AddSwitchingEvt (80,20);
909  AddAccessRequest (101, 2, 110, 0);
910  ExpectCollision (101, 0, 0); //backoff: 0 slots
911  EndTest ();
912 }
913 
914 
921 class DcfTestSuite : public TestSuite
922 {
923 public:
924  DcfTestSuite ();
925 };
926 
928  : TestSuite ("devices-wifi-dcf", UNIT)
929 {
930  AddTestCase (new DcfManagerTest, TestCase::QUICK);
931 }
932 
DcaTxopTest(DcfManagerTest *test, uint32_t i)
Constructor.
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
std::vector< Ptr< DcaTxopTest > > Dca
the DCA TXOP tests typedef
std::pair< uint64_t, uint64_t > ExpectedGrant
the expected grant typedef
Dca Txop Test.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
void NotifySleep(void)
When sleep operation occurs, if there is a pending packet transmission, it will be reinserted to the ...
static DcfTestSuite g_dcfTestSuite
A suite of tests to run.
Definition: test.h:1342
ExpectedCollision structure.
ExpectedCollisions m_expectedInternalCollision
expected internal collisions
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void AddRxOkEvt(uint64_t at, uint64_t duration)
Add expect collision function.
void AddAccessRequestWithAckTimeout(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access request with ack timeout.
void AddSwitchingEvt(uint64_t at, uint64_t duration)
Add switching event function.
void EndTest(void)
End test function.
#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:285
void SetAifsn(uint32_t aifsn)
Definition: dcf-state.cc:67
std::list< ExpectedGrant > ExpectedGrants
the collection of expected grants typedef
void AddTxEvt(uint64_t at, uint64_t duration)
Add transmit event function.
encapsulates test code
Definition: test.h:1155
void NotifyInternalCollision(void)
Notify the DCF that internal collision has occurred.
void DoDispose(void)
Destructor implementation.
void AddRxInsideSifsEvt(uint64_t at, uint64_t duration)
Add receive inside SIFS event function.
void NotifyChannelSwitching(uint32_t i)
Notify channel switching function.
void NotifyAccessGranted(void)
Notify the DCF that access has been granted.
void StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20)
Start test function.
ExpectedCollisions m_expectedCollision
expected collision
void AddAckTimeoutReset(uint64_t at)
Add ack timeout reset function.
uint32_t m_i
the DCF state
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void NotifyTxStartNow(Time duration)
Definition: dcf-manager.cc:572
void NotifyAckTimeoutStartNow(Time duration)
Notify that ACK timer has started for the given duration.
Definition: dcf-manager.cc:734
void NotifyCollision(uint32_t i)
Notify collision function.
keep track of the state needed for a single DCF function.
Definition: dcf-state.h:41
void NotifyChannelSwitching(void)
When a channel switching occurs, enqueued packets are removed.
void AddNavReset(uint64_t at, uint64_t duration)
Add NAV reset function.
void ExpectCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
void AddCcaBusyEvt(uint64_t at, uint64_t duration)
Add CCA busy event function.
Dcf Test Suite.
void NotifyCollision(void)
Notify the DCF that collision has occurred.
void ExpectInternalCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
uint32_t nSlots
number of slots
void StartBackoffNow(uint32_t nSlots)
Definition: dcf-state.cc:154
DcfStates m_dcfStates
the DCF states
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ExpectedGrants m_expectedGrants
expected grants
std::vector< Ptr< DcfStateTest > > DcfStates
the DCF test states typedef
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, Ptr< DcfStateTest > state)
Add access request with successful ack.
void Add(Ptr< DcfState > dcf)
Definition: dcf-manager.cc:190
DcfStateTest(Ptr< DcaTxop > dca)
Constructor.
void NotifyWakeUp(void)
When wake up operation occurs, channel access will be restarted.
void SetEifsNoDifs(Time eifsNoDifs)
Definition: dcf-manager.cc:176
uint32_t m_ackTimeoutValue
the ack timeout value
void AddRxStartEvt(uint64_t at, uint64_t duration)
Add receive start event function.
std::list< struct ExpectedCollision > ExpectedCollisions
expected collisions typedef
void SetSlot(Time slotTime)
Definition: dcf-manager.cc:162
void NotifyAccessGranted(uint32_t i)
Notify access granted function.
void NotifyInternalCollision(uint32_t i)
Notify internal collision function.
Dcf State Test.
void RequestAccess(Ptr< DcfState > state)
Definition: dcf-manager.cc:292
void AddNavStart(uint64_t at, uint64_t duration)
Add NAV start function.
DcfManagerTest * m_test
the test DCF manager
void AddAccessRequest(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access function.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1009
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
void AddDcfState(uint32_t aifsn)
Add DCF state function.
void AddAccessRequestWithSuccessfullAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
Add access request with successful ack.
Dcf Manager Test.
handle packet fragmentation and retransmissions.
Definition: dca-txop.h:58
void AddRxErrorEvt(uint64_t at, uint64_t duration)
Add receive error event function.
Ptr< DcfManager > m_dcfManager
the DCF manager
void SetSifs(Time sifs)
Definition: dcf-manager.cc:169
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
Queue transmit function.
virtual void DoRun(void)
Implementation to actually run this TestCase.