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