A Discrete-Event Network Simulator
API
channel-access-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/channel-access-manager.h"
24 #include "ns3/txop.h"
25 #include "ns3/mac-low.h"
26 
27 using namespace ns3;
28 
30 
37 class TxopTest : public Txop
38 {
39 public:
46  TxopTest (ChannelAccessManagerTest *test, uint32_t i);
47 
53  void QueueTx (uint64_t txTime, uint64_t expectedGrantTime);
54 
55 private:
58 
59  typedef std::pair<uint64_t,uint64_t> ExpectedGrant;
60  typedef std::list<ExpectedGrant> ExpectedGrants;
61  struct ExpectedCollision
63  {
64  uint64_t at;
65  uint32_t nSlots;
66  };
67  typedef std::list<struct ExpectedCollision> ExpectedCollisions;
68 
72 
73  bool IsAccessRequested (void) const;
74  void NotifyAccessRequested (void);
75  void NotifyAccessGranted (void);
76  void NotifyInternalCollision (void);
77  void NotifyCollision (void);
78  void NotifyChannelSwitching (void);
79  void NotifySleep (void);
80  void NotifyWakeUp (void);
81  void DoDispose (void);
82 
84  uint32_t m_i;
86 };
87 
94 class MacLowStub : public MacLow
95 {
96 public:
98  {
99  }
103  bool IsCfPeriod (void) const
104  {
105  return false;
106  }
107 };
108 
116 {
117 public:
119  virtual void DoRun (void);
120 
125  void NotifyAccessGranted (uint32_t i);
130  void NotifyInternalCollision (uint32_t i);
135  void NotifyCollision (uint32_t i);
140  void NotifyChannelSwitching (uint32_t i);
141 
142 
143 private:
151  void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
156  void AddDcfState (uint32_t aifsn);
158  void EndTest (void);
165  void ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from);
172  void ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from);
178  void AddRxOkEvt (uint64_t at, uint64_t duration);
184  void AddRxErrorEvt (uint64_t at, uint64_t duration);
190  void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
196  void AddTxEvt (uint64_t at, uint64_t duration);
202  void AddNavReset (uint64_t at, uint64_t duration);
208  void AddNavStart (uint64_t at, uint64_t duration);
213  void AddAckTimeoutReset (uint64_t at);
221  void AddAccessRequest (uint64_t at, uint64_t txTime,
222  uint64_t expectedGrantTime, uint32_t from);
230  void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
231  uint64_t expectedGrantTime, uint32_t from);
240  void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
241  uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
248  void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, Ptr<TxopTest> state);
254  void AddCcaBusyEvt (uint64_t at, uint64_t duration);
260  void AddSwitchingEvt (uint64_t at, uint64_t duration);
266  void AddRxStartEvt (uint64_t at, uint64_t duration);
267 
268  typedef std::vector<Ptr<TxopTest> > TxopTests;
269 
273  uint32_t m_ackTimeoutValue;
274 };
275 
276 void
277 TxopTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime)
278 {
279  m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
280 }
281 
283  : m_test (test),
284  m_i (i),
285  m_accessRequested (false)
286 {
287 }
288 
289 void
291 {
292  m_test = 0;
293  Txop::DoDispose ();
294 }
295 
296 bool
298 {
299  return m_accessRequested;
300 }
301 
302 void
304 {
305  m_accessRequested = true;
306 }
307 
308 void
310 {
311  m_accessRequested = false;
313 }
314 
315 void
317 {
319 }
320 
321 void
323 {
325 }
326 
327 void
329 {
331 }
332 
333 void
335 {
336 }
337 
338 void
340 {
341 }
342 
344  : TestCase ("ChannelAccessManager")
345 {
346 }
347 
348 void
350 {
351  Ptr<TxopTest> state = m_txop[i];
352  NS_TEST_EXPECT_MSG_EQ (state->m_expectedGrants.empty (), false, "Have expected grants");
353  if (!state->m_expectedGrants.empty ())
354  {
355  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
356  state->m_expectedGrants.pop_front ();
357  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected access grant is now");
360  }
361 }
362 
363 void
364 ChannelAccessManagerTest::AddTxEvt (uint64_t at, uint64_t duration)
365 {
366  Simulator::Schedule (MicroSeconds (at) - Now (),
367  &ChannelAccessManager::NotifyTxStartNow, m_ChannelAccessManager,
368  MicroSeconds (duration));
369 }
370 
371 void
373 {
374  Ptr<TxopTest> state = m_txop[i];
375  NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (), false, "Have expected internal collisions");
376  if (!state->m_expectedInternalCollision.empty ())
377  {
378  struct TxopTest::ExpectedCollision expected = state->m_expectedInternalCollision.front ();
379  state->m_expectedInternalCollision.pop_front ();
380  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected internal collision time is now");
381  state->StartBackoffNow (expected.nSlots);
382  }
383 }
384 
385 void
387 {
388  Ptr<TxopTest> state = m_txop[i];
389  NS_TEST_EXPECT_MSG_EQ (state->m_expectedCollision.empty (), false, "Have expected collisions");
390  if (!state->m_expectedCollision.empty ())
391  {
392  struct TxopTest::ExpectedCollision expected = state->m_expectedCollision.front ();
393  state->m_expectedCollision.pop_front ();
394  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected collision is now");
395  state->StartBackoffNow (expected.nSlots);
396  }
397 }
398 
399 void
401 {
402  Ptr<TxopTest> state = m_txop[i];
403  if (!state->m_expectedGrants.empty ())
404  {
405  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
406  state->m_expectedGrants.pop_front ();
407  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected grant is now");
408  }
409  state->m_accessRequested = false;
410 }
411 
412 void
413 ChannelAccessManagerTest::ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from)
414 {
415  Ptr<TxopTest> state = m_txop[from];
416  struct TxopTest::ExpectedCollision col;
417  col.at = time;
418  col.nSlots = nSlots;
419  state->m_expectedInternalCollision.push_back (col);
420 }
421 
422 void
423 ChannelAccessManagerTest::ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from)
424 {
425  Ptr<TxopTest> state = m_txop[from];
426  struct TxopTest::ExpectedCollision col;
427  col.at = time;
428  col.nSlots = nSlots;
429  state->m_expectedCollision.push_back (col);
430 }
431 
432 void
433 ChannelAccessManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue)
434 {
435  m_ChannelAccessManager = CreateObject<ChannelAccessManager> ();
436  m_low = CreateObject<MacLowStub> ();
440  m_ChannelAccessManager->SetEifsNoDifs (MicroSeconds (eifsNoDifsNoSifs + sifs));
441  m_ackTimeoutValue = ackTimeoutValue;
442 }
443 
444 void
446 {
447  Ptr<TxopTest> txop = CreateObject<TxopTest> (this, m_txop.size ());
448  txop->SetAifsn (aifsn);
449  m_txop.push_back (txop);
450  m_ChannelAccessManager->Add (txop);
451 }
452 
453 void
455 {
456  Simulator::Run ();
457  Simulator::Destroy ();
458 
459  for (TxopTests::const_iterator i = m_txop.begin (); i != m_txop.end (); i++)
460  {
461  Ptr<TxopTest> state = *i;
462  NS_TEST_EXPECT_MSG_EQ (state->m_expectedGrants.empty (), true, "Have no expected grants");
463  NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (), true, "Have no internal collisions");
464  NS_TEST_EXPECT_MSG_EQ (state->m_expectedCollision.empty (), true, "Have no expected collisions");
465  state = 0;
466  }
467  m_txop.clear ();
468 
469  for (TxopTests::const_iterator i = m_txop.begin (); i != m_txop.end (); i++)
470  {
471  Ptr<TxopTest> txop = *i;
472  txop->Dispose ();
473  txop = 0;
474  }
475  m_txop.clear ();
476 
478  m_low = 0;
479 }
480 
481 void
482 ChannelAccessManagerTest::AddRxOkEvt (uint64_t at, uint64_t duration)
483 {
484  Simulator::Schedule (MicroSeconds (at) - Now (),
485  &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
486  MicroSeconds (duration));
487  Simulator::Schedule (MicroSeconds (at + duration) - Now (),
488  &ChannelAccessManager::NotifyRxEndOkNow, m_ChannelAccessManager);
489 }
490 
491 void
493 {
494  Simulator::Schedule (MicroSeconds (at) - Now (),
495  &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
496  MicroSeconds (duration));
497 }
498 
499 void
500 ChannelAccessManagerTest::AddRxErrorEvt (uint64_t at, uint64_t duration)
501 {
502  Simulator::Schedule (MicroSeconds (at) - Now (),
503  &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
504  MicroSeconds (duration));
505  Simulator::Schedule (MicroSeconds (at + duration) - Now (),
506  &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
507 }
508 
509 void
510 ChannelAccessManagerTest::AddNavReset (uint64_t at, uint64_t duration)
511 {
512  Simulator::Schedule (MicroSeconds (at) - Now (),
513  &ChannelAccessManager::NotifyNavResetNow, m_ChannelAccessManager,
514  MicroSeconds (duration));
515 }
516 
517 void
518 ChannelAccessManagerTest::AddNavStart (uint64_t at, uint64_t duration)
519 {
520  Simulator::Schedule (MicroSeconds (at) - Now (),
521  &ChannelAccessManager::NotifyNavStartNow, m_ChannelAccessManager,
522  MicroSeconds (duration));
523 }
524 
525 void
527 {
528  Simulator::Schedule (MicroSeconds (at) - Now (),
529  &ChannelAccessManager::NotifyAckTimeoutResetNow, m_ChannelAccessManager);
530 }
531 
532 void
534  uint64_t expectedGrantTime, uint32_t from)
535 {
536  AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
537 }
538 
539 void
541  uint64_t expectedGrantTime, uint32_t from)
542 {
543  Simulator::Schedule (MicroSeconds (at) - Now (),
545  txTime, expectedGrantTime, m_txop[from]);
546 }
547 
548 void
550  uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
551 {
552  NS_ASSERT (ackDelay < m_ackTimeoutValue);
553  Simulator::Schedule (MicroSeconds (at) - Now (),
555  txTime, expectedGrantTime, m_txop[from]);
556  AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
557 }
558 
559 void
560 ChannelAccessManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, Ptr<TxopTest> state)
561 {
562  state->QueueTx (txTime, expectedGrantTime);
564 }
565 
566 void
567 ChannelAccessManagerTest::AddCcaBusyEvt (uint64_t at, uint64_t duration)
568 {
569  Simulator::Schedule (MicroSeconds (at) - Now (),
570  &ChannelAccessManager::NotifyMaybeCcaBusyStartNow, m_ChannelAccessManager,
571  MicroSeconds (duration));
572 }
573 
574 void
575 ChannelAccessManagerTest::AddSwitchingEvt (uint64_t at, uint64_t duration)
576 {
577  Simulator::Schedule (MicroSeconds (at) - Now (),
578  &ChannelAccessManager::NotifySwitchingStartNow, m_ChannelAccessManager,
579  MicroSeconds (duration));
580 }
581 
582 void
583 ChannelAccessManagerTest::AddRxStartEvt (uint64_t at, uint64_t duration)
584 {
585  Simulator::Schedule (MicroSeconds (at) - Now (),
586  &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
587  MicroSeconds (duration));
588 }
589 
590 void
592 {
593  // Bug 2369 addresses this case
594  // 0 3 4 5 8 9 10 12
595  // | sifs | aifsn | tx | sifs | aifsn | | tx |
596  //
597  StartTest (1, 3, 10);
598  AddDcfState (1);
599  AddAccessRequest (1, 1, 4, 0);
600  // Generate backoff when the request is within SIFS
601  ExpectCollision (1, 0, 0); // 0 slots
602  AddAccessRequest (10, 2, 10, 0);
603  EndTest ();
604  // Bug 2369 addresses this case
605  // 0 3 5 6 9 11 12 13
606  // | sifs | aifsn | tx | sifs | aifsn | | tx |
607  //
608  StartTest (1, 3, 10);
609  AddDcfState (2);
610  AddAccessRequest (4, 1, 5, 0);
611  // Generate backoff when the request is within AIFSN
612  ExpectCollision (4, 0, 0); // 0 slots
613  AddAccessRequest (12, 2, 12, 0);
614  EndTest ();
615  // Check that receiving inside SIFS shall be cancelled properly:
616  // 0 3 4 5 8 9 12 13 14
617  // | sifs | aifsn | tx | sifs | ack | sifs | aifsn | |tx |
618  //
619 
620  StartTest (1, 3, 10);
621  AddDcfState (1);
622  AddAccessRequest (1, 1, 4, 0);
623  ExpectCollision (1, 0, 0);
624  AddRxInsideSifsEvt (6, 10);
625  AddTxEvt (8, 1);
626  AddAccessRequest (14, 2, 14, 0);
627  EndTest ();
628  // The test below mainly intends to test the case where the medium
629  // becomes busy in the middle of a backoff slot: the backoff counter
630  // must not be decremented for this backoff slot. This is the case
631  // below for the backoff slot starting at time 78us.
632  //
633  // 20 60 66 70 74 78 80 100 106 110 114 118 120
634  // | rx | sifs | aifsn | bslot0 | bslot1 | | rx | sifs | aifsn | bslot2 | bslot3 | tx |
635  // |
636  // 30 request access. backoff slots: 4
637 
638  StartTest (4, 6, 10);
639  AddDcfState (1);
640  AddRxOkEvt (20, 40);
641  AddRxOkEvt (80, 20);
642  AddAccessRequest (30, 2, 118, 0);
643  ExpectCollision (30, 4, 0); //backoff: 4 slots
644  EndTest ();
645  // Test the case where the backoff slots is zero.
646  //
647  // 20 60 66 70 72
648  // | 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  AddAccessRequest (30, 2, 70, 0);
656  ExpectCollision (30, 0, 0); // backoff: 0 slots
657  EndTest ();
658  // Test shows when two frames are received without interval between
659  // them:
660  // 20 60 100 106 110 112
661  // | rx | rx |sifs | aifsn | tx |
662  // |
663  // 30 request access. backoff slots: 0
664 
665  StartTest (4, 6, 10);
666  AddDcfState (1);
667  AddRxOkEvt (20, 40);
668  AddRxOkEvt (60, 40);
669  AddAccessRequest (30, 2, 110, 0);
670  ExpectCollision (30, 0, 0); //backoff: 0 slots
671  EndTest ();
672 
673  // Bug 2369. Test case of requesting access within SIFS interval
674  //
675  // 20 60 66 70 74
676  // | rx | sifs | aifsn | backoff | tx |
677  // |
678  // 62 request access.
679  //
680  StartTest (4, 6, 10);
681  AddDcfState (1);
682  AddRxOkEvt (20, 40);
683  AddAccessRequest (62, 2, 74, 0);
684  ExpectCollision (62, 1, 0); //backoff: 1 slots
685  EndTest ();
686 
687  // Bug 2369. Test case of requesting access after DIFS (no backoff)
688  //
689  // 20 60 66 70
690  // | rx | sifs | aifsn | tx |
691  // |
692  // 70 request access.
693  //
694  StartTest (4, 6, 10);
695  AddDcfState (1);
696  AddRxOkEvt (20, 40);
697  AddAccessRequest (70, 2, 70, 0);
698  EndTest ();
699 
700  // Test an EIFS
701  //
702  // 20 60 66 76 86 90 94 98 102 106
703  // | rx | sifs | acktxttime | 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, 102, 0);
710  ExpectCollision (30, 4, 0); //backoff: 4 slots
711  EndTest ();
712 
713  // Test an EIFS which is interrupted by a successful transmission.
714  //
715  // 20 60 66 69 75 81 85 89 93 97 101 103
716  // | rx | sifs | | rx | sifs | aifsn | bslot0 | bslot1 | bslot2 | bslot3 | tx |
717  // | | <--eifs-->|
718  // 30 request access. backoff slots: 4
719  StartTest (4, 6, 10);
720  AddDcfState (1);
721  AddRxErrorEvt (20, 40);
722  AddAccessRequest (30, 2, 101, 0);
723  ExpectCollision (30, 4, 0); //backoff: 4 slots
724  AddRxOkEvt (69, 6);
725  EndTest ();
726 
727  // Test two DCFs which suffer an internal collision. the first DCF has a higher
728  // priority than the second DCF.
729  //
730  // 20 60 66 70 74 78 88
731  // DCF0 | rx | sifs | aifsn | bslot0 | bslot1 | tx |
732  // DCF1 | rx | sifs | aifsn | aifsn | aifsn | | sifs | aifsn | aifsn | aifsn | bslot | tx |
733  // 94 98 102 106 110 112
734  StartTest (4, 6, 10);
735  AddDcfState (1); //high priority DCF
736  AddDcfState (3); //low priority DCF
737  AddRxOkEvt (20, 40);
738  AddAccessRequest (30, 10, 78, 0);
739  ExpectCollision (30, 2, 0); //backoff: 2 slot
740  AddAccessRequest (40, 2, 110, 1);
741  ExpectCollision (40, 0, 1); //backoff: 0 slot
742  ExpectInternalCollision (78, 1, 1); //backoff: 1 slot
743  EndTest ();
744 
745  // Test of AckTimeout handling: First queue requests access and ack procedure fails,
746  // inside the ack timeout second queue with higher priority requests access.
747  //
748  // 20 40 50 60 66 76
749  // DCF0 - low | tx | ack timeout |sifs| |
750  // DCF1 - high | | |sifs| tx |
751  // ^ request access
752  StartTest (4, 6, 10);
753  AddDcfState (2); //high priority DCF
754  AddDcfState (0); //low priority DCF
755  AddAccessRequestWithAckTimeout (20, 20, 20, 0);
756  AddAccessRequest (50, 10, 66, 1);
757  ExpectCollision (50, 0, 1);
758  EndTest ();
759 
760  // Test of AckTimeout handling:
761  //
762  // First queue requests access and ack is 2 us delayed (got ack interval at the picture),
763  // inside this interval second queue with higher priority requests access.
764  //
765  // 20 40 41 42 48 58
766  // DCF0 - low | tx |got ack |sifs| |
767  // DCF1 - high | | |sifs| tx |
768  // ^ request access
769  StartTest (4, 6, 10);
770  AddDcfState (2); //high priority DCF
771  AddDcfState (0); //low priority DCF
772  AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
773  AddAccessRequest (41, 10, 48, 1);
774  ExpectCollision (41, 0, 1);
775  EndTest ();
776 
777  //Repeat the same but with one queue:
778  // 20 40 41 42 48 58
779  // DCF0 - low | tx |got ack |sifs| |
780  // ^ request access
781  StartTest (4, 6, 10);
782  AddDcfState (2);
783  AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
784  AddAccessRequest (41, 10, 56, 0);
785  ExpectCollision (41, 0, 0);
786  EndTest ();
787 
788  // test simple NAV count. This scenario modelizes a simple DATA+ACK handshake
789  // where the data rate used for the ACK is higher than expected by the DATA source
790  // so, the data exchange completes before the end of nav.
791  StartTest (4, 6, 10);
792  AddDcfState (1);
793  AddRxOkEvt (20, 40);
794  AddNavStart (60, 15);
795  AddRxOkEvt (66, 5);
796  AddNavStart (71, 0);
797  AddAccessRequest (30, 10, 93, 0);
798  ExpectCollision (30, 2, 0); //backoff: 2 slot
799  EndTest ();
800 
801  // test more complex NAV handling by a CF-poll. This scenario modelizes a
802  // simple DATA+ACK handshake interrupted by a CF-poll which resets the
803  // NAV counter.
804  StartTest (4, 6, 10);
805  AddDcfState (1);
806  AddRxOkEvt (20, 40);
807  AddNavStart (60, 15);
808  AddRxOkEvt (66, 5);
809  AddNavReset (71, 2);
810  AddAccessRequest (30, 10, 91, 0);
811  ExpectCollision (30, 2, 0); //backoff: 2 slot
812  EndTest ();
813 
814 
815  StartTest (4, 6, 10);
816  AddDcfState (2);
817  AddRxOkEvt (20, 40);
818  AddAccessRequest (80, 10, 80, 0);
819  EndTest ();
820 
821 
822  StartTest (4, 6, 10);
823  AddDcfState (2);
824  AddRxOkEvt (20, 40);
825  AddRxOkEvt (78, 8);
826  AddAccessRequest (30, 50, 108, 0);
827  ExpectCollision (30, 3, 0); //backoff: 3 slots
828  EndTest ();
829 
830 
831  // Channel switching tests
832 
833  // 0 20 23 24 25
834  // | switching | sifs | aifsn | tx |
835  // |
836  // 21 access request.
837  StartTest (1, 3, 10);
838  AddDcfState (1);
839  AddSwitchingEvt (0,20);
840  AddAccessRequest (21, 1, 24, 0);
841  ExpectCollision (21, 0, 0);
842  EndTest ();
843 
844  // 20 40 50 53 54 55 56 57
845  // | switching | busy | sifs | aifsn | bslot0 | bslot 1 | tx |
846  // | |
847  // 30 busy. 45 access request.
848  //
849  StartTest (1, 3, 10);
850  AddDcfState (1);
851  AddSwitchingEvt (20,20);
852  AddCcaBusyEvt (30,20);
853  ExpectCollision (45, 2, 0); //backoff: 2 slots
854  AddAccessRequest (45, 1, 56, 0);
855  EndTest ();
856 
857  // 20 30 50 53 54 55
858  // | rx | switching | sifs | aifsn | tx |
859  // |
860  // 51 access request.
861  //
862  StartTest (1, 3, 10);
863  AddDcfState (1);
864  AddRxStartEvt (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  // | busy | switching | sifs | aifsn | tx |
872  // |
873  // 51 access request.
874  //
875  StartTest (1, 3, 10);
876  AddDcfState (1);
877  AddCcaBusyEvt (20,40);
878  AddSwitchingEvt (30,20);
879  AddAccessRequest (51, 1, 54, 0);
880  ExpectCollision (51, 0, 0);
881  EndTest ();
882 
883  // 20 30 50 53 54 55
884  // | nav | switching | sifs | aifsn | tx |
885  // |
886  // 51 access request.
887  //
888  StartTest (1, 3, 10);
889  AddDcfState (1);
890  AddNavStart (20,40);
891  AddSwitchingEvt (30,20);
892  AddAccessRequest (51, 1, 54, 0);
893  ExpectCollision (51, 0, 0);
894  EndTest ();
895 
896  // 20 40 50 55 58 59 60
897  // | tx | ack timeout | switching | sifs | aifsn | tx |
898  // | |
899  // 45 access request. 56 access request.
900  //
901  StartTest (1, 3, 10);
902  AddDcfState (1);
903  AddAccessRequestWithAckTimeout (20, 20, 20, 0);
904  AddAccessRequest (45, 1, 50, 0);
905  ExpectCollision (45, 0, 0);
906  AddSwitchingEvt (50,5);
907  AddAccessRequest (56, 1, 59, 0);
908  ExpectCollision (56, 0, 0);
909  EndTest ();
910 
911  // 20 60 66 70 74 78 80 100 106 110 112
912  // | rx | sifs | aifsn | bslot0 | bslot1 | | switching | sifs | aifsn | tx |
913  // | |
914  // 30 access request. 101 access request.
915  //
916  StartTest (4, 6, 10);
917  AddDcfState (1);
918  AddRxOkEvt (20,40);
919  AddAccessRequest (30, 2, 80, 0);
920  ExpectCollision (30, 4, 0); //backoff: 4 slots
921  AddSwitchingEvt (80,20);
922  AddAccessRequest (101, 2, 110, 0);
923  ExpectCollision (101, 0, 0); //backoff: 0 slots
924  EndTest ();
925 }
926 
927 
934 class DcfTestSuite : public TestSuite
935 {
936 public:
937  DcfTestSuite ();
938 };
939 
941  : TestSuite ("devices-wifi-dcf", UNIT)
942 {
943  AddTestCase (new ChannelAccessManagerTest, TestCase::QUICK);
944 }
945 
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
Ptr< MacLowStub > m_low
the MAC low stubbed
void AddRxOkEvt(uint64_t at, uint64_t duration)
Add expect collision function.
void NotifyAccessGranted(void)
Notify the DCF that access has been granted.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
ExpectedCollision structure.
ExpectedCollisions m_expectedCollision
expected collision
void NotifyCollision(void)
Notify the DCF that collision has occurred.
void NotifyChannelSwitching(uint32_t i)
Notify channel switching function.
uint32_t m_ackTimeoutValue
the ack timeout value
TxopTest Txop Test.
A suite of tests to run.
Definition: test.h:1342
bool IsCfPeriod(void) const
This function indicates whether it is the CF period.
#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
ChannelAccessManagerTest * m_test
the test DCF manager
#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 NotifyCollision(uint32_t i)
Notify collision function.
encapsulates test code
Definition: test.h:1155
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
Queue transmit function.
bool IsAccessRequested(void) const
std::list< ExpectedGrant > ExpectedGrants
the collection of expected grants typedef
void NotifyChannelSwitching(void)
When a channel switching occurs, enqueued packets are removed.
void EndTest(void)
End test function.
TxopTest(ChannelAccessManagerTest *test, uint32_t i)
Constructor.
void AddDcfState(uint32_t aifsn)
Add DCF state function.
std::vector< Ptr< TxopTest > > TxopTests
the TXOP tests typedef
void SetEifsNoDifs(Time eifsNoDifs)
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void NotifyWakeUp(void)
When wake up operation occurs, channel access will be restarted.
void AddRxInsideSifsEvt(uint64_t at, uint64_t duration)
Add receive inside SIFS event function.
void AddAccessRequest(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access function.
void ExpectCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
Ptr< ChannelAccessManager > m_ChannelAccessManager
the DCF manager
void AddSwitchingEvt(uint64_t at, uint64_t duration)
Add switching event function.
void AddAccessRequestWithAckTimeout(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access request with ack timeout.
void AddAccessRequestWithSuccessfullAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
Add access request with successful ack.
void AddCcaBusyEvt(uint64_t at, uint64_t duration)
Add CCA busy event function.
void DoDispose(void)
Destructor implementation.
void NotifyInternalCollision(void)
Notify the DCF that internal collision has occurred.
void NotifyAckTimeoutStartNow(Time duration)
Notify that ACK timer has started for the given duration.
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, Ptr< TxopTest > state)
Add access request with successful ack.
void NotifyInternalCollision(uint32_t i)
Notify internal collision function.
void AddNavStart(uint64_t at, uint64_t duration)
Add NAV start function.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t m_i
the DCF state
void AddRxErrorEvt(uint64_t at, uint64_t duration)
Add receive error event function.
void ExpectInternalCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
bool m_accessRequested
true if access requested
static DcfTestSuite g_dcfTestSuite
void StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20)
Start test function.
void AddAckTimeoutReset(uint64_t at)
Add ack timeout reset function.
std::list< struct ExpectedCollision > ExpectedCollisions
expected collisions typedef
void AddNavReset(uint64_t at, uint64_t duration)
Add NAV reset function.
handle RTS/CTS/DATA/ACK transactions.
Definition: mac-low.h:59
void AddTxEvt(uint64_t at, uint64_t duration)
Add transmit event function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddRxStartEvt(uint64_t at, uint64_t duration)
Add receive start event function.
std::pair< uint64_t, uint64_t > ExpectedGrant
the expected grant typedef
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1078
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:309
void NotifyAccessGranted(uint32_t i)
Notify access granted function.
void SetAifsn(uint8_t aifsn)
Set the number of slots that make up an AIFS.
Definition: txop.cc:269
void NotifyTxStartNow(Time duration)
ExpectedGrants m_expectedGrants
expected grants
void SetupLow(Ptr< MacLow > low)
Set up listener for MacLow events.
void NotifyAccessRequested(void)
Notify that access request has been received.
void StartBackoffNow(uint32_t nSlots)
Definition: txop.cc:253
void RequestAccess(Ptr< Txop > state, bool isCfPeriod=false)
void NotifySleep(void)
When sleep operation occurs, if there is a pending packet transmission, it will be reinserted to the ...
ExpectedCollisions m_expectedInternalCollision
expected internal collisions
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:65