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-manager.h"
24 
25 using namespace ns3;
26 
27 class DcfManagerTest;
28 
29 class DcfStateTest : public DcfState
30 {
31 public:
32  DcfStateTest (DcfManagerTest *test, uint32_t i);
33  void QueueTx (uint64_t txTime, uint64_t expectedGrantTime);
34  bool IsEdca (void) const;
35 
36 
37 private:
38  friend class DcfManagerTest;
39  virtual void DoNotifyAccessGranted (void);
40  virtual void DoNotifyInternalCollision (void);
41  virtual void DoNotifyCollision (void);
42  virtual void DoNotifyChannelSwitching (void);
43  virtual void DoNotifySleep (void);
44  virtual void DoNotifyWakeUp (void);
45 
46  typedef std::pair<uint64_t,uint64_t> ExpectedGrant;
47  typedef std::list<ExpectedGrant> ExpectedGrants;
49  {
50  uint64_t at;
51  uint32_t nSlots;
52  };
53  typedef std::list<struct ExpectedCollision> ExpectedCollisions;
54 
55  ExpectedCollisions m_expectedInternalCollision;
56  ExpectedCollisions m_expectedCollision;
57  ExpectedGrants m_expectedGrants;
59  uint32_t m_i;
60 };
61 
62 
63 class DcfManagerTest : public TestCase
64 {
65 public:
66  DcfManagerTest ();
67  virtual void DoRun (void);
68 
69  void NotifyAccessGranted (uint32_t i);
70  void NotifyInternalCollision (uint32_t i);
71  void NotifyCollision (uint32_t i);
72  void NotifyChannelSwitching (uint32_t i);
73 
74 
75 private:
76  void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
77  void AddDcfState (uint32_t aifsn);
78  void EndTest (void);
79  void ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from);
80  void ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from);
81  void AddRxOkEvt (uint64_t at, uint64_t duration);
82  void AddRxErrorEvt (uint64_t at, uint64_t duration);
83  void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
84  void AddTxEvt (uint64_t at, uint64_t duration);
85  void AddNavReset (uint64_t at, uint64_t duration);
86  void AddNavStart (uint64_t at, uint64_t duration);
87  void AddAckTimeoutReset (uint64_t at);
88  void AddAccessRequest (uint64_t at, uint64_t txTime,
89  uint64_t expectedGrantTime, uint32_t from);
90  void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
91  uint64_t expectedGrantTime, uint32_t from);
97  void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
98  uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
99  void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state);
100  void AddCcaBusyEvt (uint64_t at, uint64_t duration);
101  void AddSwitchingEvt (uint64_t at, uint64_t duration);
102  void AddRxStartEvt (uint64_t at, uint64_t duration);
103 
104  typedef std::vector<DcfStateTest *> DcfStates;
105 
107  DcfStates m_dcfStates;
109 };
110 
112  : m_test (test),
113  m_i (i)
114 {
115 }
116 
117 bool
119 {
120  return false;
121 }
122 
123 void
124 DcfStateTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime)
125 {
126  m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
127 }
128 
129 void
131 {
133 }
134 
135 void
137 {
139 }
140 
141 void
143 {
145 }
146 
147 void
149 {
151 }
152 
153 void
155 {
156 }
157 
158 void
160 {
161 }
162 
164  : TestCase ("DcfManager")
165 {
166 }
167 
168 void
170 {
171  DcfStateTest *state = m_dcfStates[i];
172  NS_TEST_EXPECT_MSG_EQ (state->m_expectedGrants.empty (), false, "Have expected grants");
173  if (!state->m_expectedGrants.empty ())
174  {
175  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
176  state->m_expectedGrants.pop_front ();
177  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected access grant is now");
178  m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.first));
180  }
181 }
182 
183 void
184 DcfManagerTest::AddTxEvt (uint64_t at, uint64_t duration)
185 {
186  Simulator::Schedule (MicroSeconds (at) - Now (),
187  &DcfManager::NotifyTxStartNow, m_dcfManager,
188  MicroSeconds (duration));
189 }
190 
191 void
193 {
194  DcfStateTest *state = m_dcfStates[i];
195  NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (), false, "Have expected internal collisions");
196  if (!state->m_expectedInternalCollision.empty ())
197  {
198  struct DcfStateTest::ExpectedCollision expected = state->m_expectedInternalCollision.front ();
199  state->m_expectedInternalCollision.pop_front ();
200  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected internal collision time is now");
201  state->StartBackoffNow (expected.nSlots);
202  }
203 }
204 
205 void
207 {
208  DcfStateTest *state = m_dcfStates[i];
209  NS_TEST_EXPECT_MSG_EQ (state->m_expectedCollision.empty (), false, "Have expected collisions");
210  if (!state->m_expectedCollision.empty ())
211  {
212  struct DcfStateTest::ExpectedCollision expected = state->m_expectedCollision.front ();
213  state->m_expectedCollision.pop_front ();
214  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected collision is now");
215  state->StartBackoffNow (expected.nSlots);
216  }
217 }
218 
219 void
221 {
222  DcfStateTest *state = m_dcfStates[i];
223  if (!state->m_expectedGrants.empty ())
224  {
225  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
226  state->m_expectedGrants.pop_front ();
227  NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected grant is now");
228  }
229 }
230 
231 void
232 DcfManagerTest::ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from)
233 {
234  DcfStateTest *state = m_dcfStates[from];
236  col.at = time;
237  col.nSlots = nSlots;
238  state->m_expectedInternalCollision.push_back (col);
239 }
240 
241 void
242 DcfManagerTest::ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from)
243 {
244  DcfStateTest *state = m_dcfStates[from];
246  col.at = time;
247  col.nSlots = nSlots;
248  state->m_expectedCollision.push_back (col);
249 }
250 
251 void
252 DcfManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue)
253 {
254  m_dcfManager = new DcfManager ();
255  m_dcfManager->SetSlot (MicroSeconds (slotTime));
257  m_dcfManager->SetEifsNoDifs (MicroSeconds (eifsNoDifsNoSifs + sifs));
258  m_ackTimeoutValue = ackTimeoutValue;
259 }
260 
261 void
263 {
264  DcfStateTest *state = new DcfStateTest (this, m_dcfStates.size ());
265  state->SetAifsn (aifsn);
266  m_dcfStates.push_back (state);
267  m_dcfManager->Add (state);
268 }
269 
270 void
272 {
273  Simulator::Run ();
274  Simulator::Destroy ();
275  for (DcfStates::const_iterator i = m_dcfStates.begin (); i != m_dcfStates.end (); i++)
276  {
277  DcfStateTest *state = *i;
278  NS_TEST_EXPECT_MSG_EQ (state->m_expectedGrants.empty (), true, "Have no expected grants");
279  NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (), true, "Have no internal collisions");
280  NS_TEST_EXPECT_MSG_EQ (state->m_expectedCollision.empty (), true, "Have no expected collisions");
281  delete state;
282  }
283  m_dcfStates.clear ();
284  delete m_dcfManager;
285 }
286 
287 void
288 DcfManagerTest::AddRxOkEvt (uint64_t at, uint64_t duration)
289 {
290  Simulator::Schedule (MicroSeconds (at) - Now (),
291  &DcfManager::NotifyRxStartNow, m_dcfManager,
292  MicroSeconds (duration));
293  Simulator::Schedule (MicroSeconds (at + duration) - Now (),
294  &DcfManager::NotifyRxEndOkNow, m_dcfManager);
295 }
296 
297 void
298 DcfManagerTest::AddRxInsideSifsEvt (uint64_t at, uint64_t duration)
299 {
300  Simulator::Schedule (MicroSeconds (at) - Now (),
301  &DcfManager::NotifyRxStartNow, m_dcfManager,
302  MicroSeconds (duration));
303 }
304 
305 void
306 DcfManagerTest::AddRxErrorEvt (uint64_t at, uint64_t duration)
307 {
308  Simulator::Schedule (MicroSeconds (at) - Now (),
309  &DcfManager::NotifyRxStartNow, m_dcfManager,
310  MicroSeconds (duration));
311  Simulator::Schedule (MicroSeconds (at + duration) - Now (),
312  &DcfManager::NotifyRxEndErrorNow, m_dcfManager);
313 }
314 
315 void
316 DcfManagerTest::AddNavReset (uint64_t at, uint64_t duration)
317 {
318  Simulator::Schedule (MicroSeconds (at) - Now (),
319  &DcfManager::NotifyNavResetNow, m_dcfManager,
320  MicroSeconds (duration));
321 }
322 
323 void
324 DcfManagerTest::AddNavStart (uint64_t at, uint64_t duration)
325 {
326  Simulator::Schedule (MicroSeconds (at) - Now (),
327  &DcfManager::NotifyNavStartNow, m_dcfManager,
328  MicroSeconds (duration));
329 }
330 
331 void
333 {
334  Simulator::Schedule (MicroSeconds (at) - Now (),
335  &DcfManager::NotifyAckTimeoutResetNow, m_dcfManager);
336 }
337 
338 void
339 DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime,
340  uint64_t expectedGrantTime, uint32_t from)
341 {
342  AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
343 }
344 
345 void
347  uint64_t expectedGrantTime, uint32_t from)
348 {
349  Simulator::Schedule (MicroSeconds (at) - Now (),
351  txTime, expectedGrantTime, m_dcfStates[from]);
352 }
353 
354 void
356  uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
357 {
358  NS_ASSERT (ackDelay < m_ackTimeoutValue);
359  Simulator::Schedule (MicroSeconds (at) - Now (),
361  txTime, expectedGrantTime, m_dcfStates[from]);
362  AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
363 }
364 
365 void
366 DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state)
367 {
368  state->QueueTx (txTime, expectedGrantTime);
369  m_dcfManager->RequestAccess (state);
370 }
371 
372 void
373 DcfManagerTest::AddCcaBusyEvt (uint64_t at, uint64_t duration)
374 {
375  Simulator::Schedule (MicroSeconds (at) - Now (),
376  &DcfManager::NotifyMaybeCcaBusyStartNow, m_dcfManager,
377  MicroSeconds (duration));
378 }
379 
380 void
381 DcfManagerTest::AddSwitchingEvt (uint64_t at, uint64_t duration)
382 {
383  Simulator::Schedule (MicroSeconds (at) - Now (),
384  &DcfManager::NotifySwitchingStartNow, m_dcfManager,
385  MicroSeconds (duration));
386 }
387 
388 void
389 DcfManagerTest::AddRxStartEvt (uint64_t at, uint64_t duration)
390 {
391  Simulator::Schedule (MicroSeconds (at) - Now (),
392  &DcfManager::NotifyRxStartNow, m_dcfManager,
393  MicroSeconds (duration));
394 }
395 
396 void
398 {
399  // Bug 2369 addresses this case
400  // 0 3 4 5 8 9 10 12
401  // | sifs | aifsn | tx | sifs | aifsn | | tx |
402  //
403  StartTest (1, 3, 10);
404  AddDcfState (1);
405  AddAccessRequest (1, 1, 4, 0);
406  // Generate backoff when the request is within SIFS
407  ExpectCollision (1, 0, 0); // 0 slots
408  AddAccessRequest (10, 2, 10, 0);
409  EndTest ();
410  // Bug 2369 addresses this case
411  // 0 3 5 6 9 11 12 13
412  // | sifs | aifsn | tx | sifs | aifsn | | tx |
413  //
414  StartTest (1, 3, 10);
415  AddDcfState (2);
416  AddAccessRequest (4, 1, 5, 0);
417  // Generate backoff when the request is within AIFSN
418  ExpectCollision (4, 0, 0); // 0 slots
419  AddAccessRequest (12, 2, 12, 0);
420  EndTest ();
421  // Check that receiving inside SIFS shall be cancelled properly:
422  // 0 3 4 5 8 9 12 13 14
423  // | sifs | aifsn | tx | sifs | ack | sifs | aifsn | |tx |
424  //
425 
426  StartTest (1, 3, 10);
427  AddDcfState (1);
428  AddAccessRequest (1, 1, 4, 0);
429  ExpectCollision (1, 0, 0);
430  AddRxInsideSifsEvt (6, 10);
431  AddTxEvt (8, 1);
432  AddAccessRequest (14, 2, 14, 0);
433  EndTest ();
434  // The test below mainly intends to test the case where the medium
435  // becomes busy in the middle of a backoff slot: the backoff counter
436  // must not be decremented for this backoff slot. This is the case
437  // below for the backoff slot starting at time 78us.
438  //
439  // 20 60 66 70 74 78 80 100 106 110 114 118 120
440  // | rx | sifs | aifsn | bslot0 | bslot1 | | rx | sifs | aifsn | bslot2 | bslot3 | tx |
441  // |
442  // 30 request access. backoff slots: 4
443 
444  StartTest (4, 6, 10);
445  AddDcfState (1);
446  AddRxOkEvt (20, 40);
447  AddRxOkEvt (80, 20);
448  AddAccessRequest (30, 2, 118, 0);
449  ExpectCollision (30, 4, 0); //backoff: 4 slots
450  EndTest ();
451  // Test the case where the backoff slots is zero.
452  //
453  // 20 60 66 70 72
454  // | rx | sifs | aifsn | tx |
455  // |
456  // 30 request access. backoff slots: 0
457 
458  StartTest (4, 6, 10);
459  AddDcfState (1);
460  AddRxOkEvt (20, 40);
461  AddAccessRequest (30, 2, 70, 0);
462  ExpectCollision (30, 0, 0); // backoff: 0 slots
463  EndTest ();
464  // Test shows when two frames are received without interval between
465  // them:
466  // 20 60 100 106 110 112
467  // | rx | rx |sifs | aifsn | tx |
468  // |
469  // 30 request access. backoff slots: 0
470 
471  StartTest (4, 6, 10);
472  AddDcfState (1);
473  AddRxOkEvt (20, 40);
474  AddRxOkEvt (60, 40);
475  AddAccessRequest (30, 2, 110, 0);
476  ExpectCollision (30, 0, 0); //backoff: 0 slots
477  EndTest ();
478 
479  // Bug 2369. Test case of requesting access within SIFS interval
480  //
481  // 20 60 66 70 74
482  // | rx | sifs | aifsn | backoff | tx |
483  // |
484  // 62 request access.
485  //
486  StartTest (4, 6, 10);
487  AddDcfState (1);
488  AddRxOkEvt (20, 40);
489  AddAccessRequest (62, 2, 74, 0);
490  ExpectCollision (62, 1, 0); //backoff: 1 slots
491  EndTest ();
492 
493  // Bug 2369. Test case of requesting access after DIFS (no backoff)
494  //
495  // 20 60 66 70
496  // | rx | sifs | aifsn | tx |
497  // |
498  // 70 request access.
499  //
500  StartTest (4, 6, 10);
501  AddDcfState (1);
502  AddRxOkEvt (20, 40);
503  AddAccessRequest (70, 2, 70, 0);
504  EndTest ();
505 
506  // Test an EIFS
507  //
508  // 20 60 66 76 86 90 94 98 102 106
509  // | rx | sifs | acktxttime | sifs + aifsn | bslot0 | bslot1 | bslot2 | bslot3 | tx |
510  // | | <------eifs------>|
511  // 30 request access. backoff slots: 4
512  StartTest (4, 6, 10);
513  AddDcfState (1);
514  AddRxErrorEvt (20, 40);
515  AddAccessRequest (30, 2, 102, 0);
516  ExpectCollision (30, 4, 0); //backoff: 4 slots
517  EndTest ();
518 
519  // Test an EIFS which is interupted by a successfull transmission.
520  //
521  // 20 60 66 69 75 81 85 89 93 97 101 103
522  // | rx | sifs | | rx | sifs | aifsn | bslot0 | bslot1 | bslot2 | bslot3 | tx |
523  // | | <--eifs-->|
524  // 30 request access. backoff slots: 4
525  StartTest (4, 6, 10);
526  AddDcfState (1);
527  AddRxErrorEvt (20, 40);
528  AddAccessRequest (30, 2, 101, 0);
529  ExpectCollision (30, 4, 0); //backoff: 4 slots
530  AddRxOkEvt (69, 6);
531  EndTest ();
532 
533  // Test two DCFs which suffer an internal collision. the first DCF has a higher
534  // priority than the second DCF.
535  //
536  // 20 60 66 70 74 78 88
537  // DCF0 | rx | sifs | aifsn | bslot0 | bslot1 | tx |
538  // DCF1 | rx | sifs | aifsn | aifsn | aifsn | | sifs | aifsn | aifsn | aifsn | bslot | tx |
539  // 94 98 102 106 110 112
540  StartTest (4, 6, 10);
541  AddDcfState (1); //high priority DCF
542  AddDcfState (3); //low priority DCF
543  AddRxOkEvt (20, 40);
544  AddAccessRequest (30, 10, 78, 0);
545  ExpectCollision (30, 2, 0); //backoff: 2 slot
546  AddAccessRequest (40, 2, 110, 1);
547  ExpectCollision (40, 0, 1); //backoff: 0 slot
548  ExpectInternalCollision (78, 1, 1); //backoff: 1 slot
549  EndTest ();
550 
551  // Test of AckTimeout handling: First queue requests access and ack procedure fails,
552  // inside the ack timeout second queue with higher priority requests access.
553  //
554  // 20 40 50 60 66 76
555  // DCF0 - low | tx | ack timeout |sifs| |
556  // DCF1 - high | | |sifs| tx |
557  // ^ request access
558  StartTest (4, 6, 10);
559  AddDcfState (2); //high priority DCF
560  AddDcfState (0); //low priority DCF
561  AddAccessRequestWithAckTimeout (20, 20, 20, 0);
562  AddAccessRequest (50, 10, 66, 1);
563  ExpectCollision (50, 0, 1);
564  EndTest ();
565 
566  // Test of AckTimeout handling:
567  //
568  // First queue requests access and ack is 2 us delayed (got ack interval at the picture),
569  // inside this interval second queue with higher priority requests access.
570  //
571  // 20 40 41 42 48 58
572  // DCF0 - low | tx |got ack |sifs| |
573  // DCF1 - high | | |sifs| tx |
574  // ^ request access
575  StartTest (4, 6, 10);
576  AddDcfState (2); //high priority DCF
577  AddDcfState (0); //low priority DCF
578  AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
579  AddAccessRequest (41, 10, 48, 1);
580  ExpectCollision (41, 0, 1);
581  EndTest ();
582 
583  //Repeat the same but with one queue:
584  // 20 40 41 42 48 58
585  // DCF0 - low | tx |got ack |sifs| |
586  // ^ request access
587  StartTest (4, 6, 10);
588  AddDcfState (2);
589  AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
590  AddAccessRequest (41, 10, 56, 0);
591  ExpectCollision (41, 0, 0);
592  EndTest ();
593 
594  // test simple NAV count. This scenario modelizes a simple DATA+ACK handshake
595  // where the data rate used for the ACK is higher than expected by the DATA source
596  // so, the data exchange completes before the end of nav.
597  StartTest (4, 6, 10);
598  AddDcfState (1);
599  AddRxOkEvt (20, 40);
600  AddNavStart (60, 15);
601  AddRxOkEvt (66, 5);
602  AddNavStart (71, 0);
603  AddAccessRequest (30, 10, 93, 0);
604  ExpectCollision (30, 2, 0); //backoff: 2 slot
605  EndTest ();
606 
607  // test more complex NAV handling by a CF-poll. This scenario modelizes a
608  // simple DATA+ACK handshake interrupted by a CF-poll which resets the
609  // NAV counter.
610  StartTest (4, 6, 10);
611  AddDcfState (1);
612  AddRxOkEvt (20, 40);
613  AddNavStart (60, 15);
614  AddRxOkEvt (66, 5);
615  AddNavReset (71, 2);
616  AddAccessRequest (30, 10, 91, 0);
617  ExpectCollision (30, 2, 0); //backoff: 2 slot
618  EndTest ();
619 
620 
621  StartTest (4, 6, 10);
622  AddDcfState (2);
623  AddRxOkEvt (20, 40);
624  AddAccessRequest (80, 10, 80, 0);
625  EndTest ();
626 
627 
628  StartTest (4, 6, 10);
629  AddDcfState (2);
630  AddRxOkEvt (20, 40);
631  AddRxOkEvt (78, 8);
632  AddAccessRequest (30, 50, 108, 0);
633  ExpectCollision (30, 3, 0); //backoff: 3 slots
634  EndTest ();
635 
636 
637  // Channel switching tests
638 
639  // 0 20 23 24 25
640  // | switching | sifs | aifsn | tx |
641  // |
642  // 21 access request.
643  StartTest (1, 3, 10);
644  AddDcfState (1);
645  AddSwitchingEvt (0,20);
646  AddAccessRequest (21, 1, 24, 0);
647  ExpectCollision (21, 0, 0);
648  EndTest ();
649 
650  // 20 40 50 53 54 55 56 57
651  // | switching | busy | sifs | aifsn | bslot0 | bslot 1 | tx |
652  // | |
653  // 30 busy. 45 access request.
654  //
655  StartTest (1, 3, 10);
656  AddDcfState (1);
657  AddSwitchingEvt (20,20);
658  AddCcaBusyEvt (30,20);
659  ExpectCollision (45, 2, 0); //backoff: 2 slots
660  AddAccessRequest (45, 1, 56, 0);
661  EndTest ();
662 
663  // 20 30 50 53 54 55
664  // | rx | switching | sifs | aifsn | tx |
665  // |
666  // 51 access request.
667  //
668  StartTest (1, 3, 10);
669  AddDcfState (1);
670  AddRxStartEvt (20,40);
671  AddSwitchingEvt (30,20);
672  AddAccessRequest (51, 1, 54, 0);
673  ExpectCollision (51, 0, 0);
674  EndTest ();
675 
676  // 20 30 50 53 54 55
677  // | busy | switching | sifs | aifsn | tx |
678  // |
679  // 51 access request.
680  //
681  StartTest (1, 3, 10);
682  AddDcfState (1);
683  AddCcaBusyEvt (20,40);
684  AddSwitchingEvt (30,20);
685  AddAccessRequest (51, 1, 54, 0);
686  ExpectCollision (51, 0, 0);
687  EndTest ();
688 
689  // 20 30 50 53 54 55
690  // | nav | switching | sifs | aifsn | tx |
691  // |
692  // 51 access request.
693  //
694  StartTest (1, 3, 10);
695  AddDcfState (1);
696  AddNavStart (20,40);
697  AddSwitchingEvt (30,20);
698  AddAccessRequest (51, 1, 54, 0);
699  ExpectCollision (51, 0, 0);
700  EndTest ();
701 
702  // 20 40 50 55 58 59 60
703  // | tx | ack timeout | switching | sifs | aifsn | tx |
704  // | |
705  // 45 access request. 56 access request.
706  //
707  StartTest (1, 3, 10);
708  AddDcfState (1);
709  AddAccessRequestWithAckTimeout (20, 20, 20, 0);
710  AddAccessRequest (45, 1, 50, 0);
711  ExpectCollision (45, 0, 0);
712  AddSwitchingEvt (50,5);
713  AddAccessRequest (56, 1, 59, 0);
714  ExpectCollision (56, 0, 0);
715  EndTest ();
716 
717  // 20 60 66 70 74 78 80 100 106 110 112
718  // | rx | sifs | aifsn | bslot0 | bslot1 | | switching | sifs | aifsn | tx |
719  // | |
720  // 30 access request. 101 access request.
721  //
722  StartTest (4, 6, 10);
723  AddDcfState (1);
724  AddRxOkEvt (20,40);
725  AddAccessRequest (30, 2, 80, 0);
726  ExpectCollision (30, 4, 0); //backoff: 4 slots
727  AddSwitchingEvt (80,20);
728  AddAccessRequest (101, 2, 110, 0);
729  ExpectCollision (101, 0, 0); //backoff: 0 slots
730  EndTest ();
731 }
732 
733 
734 class DcfTestSuite : public TestSuite
735 {
736 public:
737  DcfTestSuite ();
738 };
739 
741  : TestSuite ("devices-wifi-dcf", UNIT)
742 {
743  AddTestCase (new DcfManagerTest, TestCase::QUICK);
744 }
745 
std::pair< uint64_t, uint64_t > ExpectedGrant
DcfManager * m_dcfManager
bool IsEdca(void) const
virtual void DoNotifyAccessGranted(void)
Called by DcfManager to notify a DcfState subclass that access to the medium is granted and can start...
static DcfTestSuite g_dcfTestSuite
A suite of tests to run.
Definition: test.h:1333
void RequestAccess(DcfState *state)
Definition: dcf-manager.cc:526
ExpectedCollisions m_expectedInternalCollision
#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)
void AddAccessRequestWithAckTimeout(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
DcfStateTest(DcfManagerTest *test, uint32_t i)
void AddSwitchingEvt(uint64_t at, uint64_t duration)
#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:278
void SetAifsn(uint32_t aifsn)
Definition: dcf-manager.cc:56
std::list< ExpectedGrant > ExpectedGrants
void AddTxEvt(uint64_t at, uint64_t duration)
encapsulates test code
Definition: test.h:1147
virtual void DoNotifyCollision(void)
Called by DcfManager to notify a DcfState subclass that a normal collision occured, that is, that the medium was busy when access was requested.
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state)
void AddRxInsideSifsEvt(uint64_t at, uint64_t duration)
void Add(DcfState *dcf)
Definition: dcf-manager.cc:424
void NotifyChannelSwitching(uint32_t i)
void StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20)
ExpectedCollisions m_expectedCollision
void AddAckTimeoutReset(uint64_t at)
virtual void DoNotifySleep(void)
Called by DcfManager to notify a DcfState subclass that the device has begun to sleep.
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
void NotifyTxStartNow(Time duration)
Definition: dcf-manager.cc:806
void NotifyAckTimeoutStartNow(Time duration)
Notify that ACK timer has started for the given duration.
Definition: dcf-manager.cc:982
Manage a set of ns3::DcfStateHandle a set of independent ns3::DcfState, each of which represents a si...
Definition: dcf-manager.h:279
void NotifyCollision(uint32_t i)
keep track of the state needed for a single DCF function.
Definition: dcf-manager.h:46
void AddNavReset(uint64_t at, uint64_t duration)
void ExpectCollision(uint64_t time, uint32_t nSlots, uint32_t from)
void AddCcaBusyEvt(uint64_t at, uint64_t duration)
void ExpectInternalCollision(uint64_t time, uint32_t nSlots, uint32_t from)
friend class DcfManager
Definition: dcf-manager.h:145
virtual void DoNotifyWakeUp(void)
Called by DcfManager to notify a DcfState subclass that the device has begun to wake up...
void StartBackoffNow(uint32_t nSlots)
Definition: dcf-manager.cc:136
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ExpectedGrants m_expectedGrants
void SetEifsNoDifs(Time eifsNoDifs)
Definition: dcf-manager.cc:410
uint32_t m_ackTimeoutValue
void AddRxStartEvt(uint64_t at, uint64_t duration)
std::list< struct ExpectedCollision > ExpectedCollisions
void SetSlot(Time slotTime)
Definition: dcf-manager.cc:396
DcfManagerTest * m_test
void NotifyAccessGranted(uint32_t i)
virtual void DoNotifyChannelSwitching(void)
Called by DcfManager to notify a DcfState subclass that a channel switching occured.
void NotifyInternalCollision(uint32_t i)
void AddNavStart(uint64_t at, uint64_t duration)
void AddAccessRequest(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:340
virtual void DoNotifyInternalCollision(void)
Called by DcfManager to notify a DcfState subclass that an 'internal' collision occured, that is, that the backoff timer of a higher priority DcfState expired at the same time and that access was granted to this higher priority DcfState.
void AddDcfState(uint32_t aifsn)
void AddAccessRequestWithSuccessfullAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
std::vector< DcfStateTest * > DcfStates
void AddRxErrorEvt(uint64_t at, uint64_t duration)
void test(void)
Example use of ns3::SystemThread.
void SetSifs(Time sifs)
Definition: dcf-manager.cc:403
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
virtual void DoRun(void)
Implementation to actually run this TestCase.