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