View | Details | Raw Unified | Return to bug 555
Collapse All | Expand All

(-)a/src/devices/wifi/dcf-manager-test.cc (-30 / +67 lines)
 Lines 32-46   class DcfStateTest : public DcfState Link Here 
32
{
32
{
33
public:
33
public:
34
  DcfStateTest (DcfManagerTest *test, uint32_t i);
34
  DcfStateTest (DcfManagerTest *test, uint32_t i);
35
  void QueueTx (uint64_t txTime, uint64_t expectedGrantTime);
35
  void QueueTx (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots);
36
private:
36
private:
37
  friend class DcfManagerTest;
37
  friend class DcfManagerTest;
38
  virtual void DoNotifyAccessGranted (void);
38
  virtual void DoNotifyAccessGranted (void);
39
  virtual void DoNotifyInternalCollision (void);
39
  virtual void DoNotifyInternalCollision (void);
40
  virtual void DoNotifyCollision (void);
40
  virtual void DoNotifyCollision (void);
41
41
42
  typedef std::pair<uint64_t,uint64_t> ExpectedGrant;
42
  struct ExpectedGrant {
43
  typedef std::list<ExpectedGrant> ExpectedGrants;
43
    uint64_t m_txTime;
44
    uint64_t m_expectedGrantTime;
45
    uint32_t m_nBackoffSlots;
46
  };
47
  typedef std::list<struct ExpectedGrant> ExpectedGrants;
48
44
  struct ExpectedCollision {
49
  struct ExpectedCollision {
45
    uint64_t at;
50
    uint64_t at;
46
    uint32_t nSlots;
51
    uint32_t nSlots;
 Lines 77-85   private: Link Here 
77
  void AddRxErrorEvt (uint64_t at, uint64_t duration);
82
  void AddRxErrorEvt (uint64_t at, uint64_t duration);
78
  void AddNavReset (uint64_t at, uint64_t duration);
83
  void AddNavReset (uint64_t at, uint64_t duration);
79
  void AddNavStart (uint64_t at, uint64_t duration);
84
  void AddNavStart (uint64_t at, uint64_t duration);
80
  void AddAccessRequest (uint64_t at, uint64_t txTime, 
85
  void AddAccessRequest (uint64_t at, uint64_t txTime, uint64_t expectedGrantTime,
81
                         uint64_t expectedGrantTime, uint32_t from);
86
                         uint32_t nBackoffSlots, uint32_t from);
82
  void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state);
87
  void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots, DcfStateTest *state);
83
  
88
  
84
  typedef std::vector<DcfStateTest *> DcfStates;
89
  typedef std::vector<DcfStateTest *> DcfStates;
85
90
 Lines 94-102   DcfStateTest::DcfStateTest (DcfManagerTe Link Here 
94
  : m_test (test), m_i(i)
99
  : m_test (test), m_i(i)
95
{}
100
{}
96
void 
101
void 
97
DcfStateTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime)
102
DcfStateTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots)
98
{
103
{
99
  m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
104
  struct ExpectedGrant grant;
105
  grant.m_txTime = txTime;
106
  grant.m_expectedGrantTime = expectedGrantTime;
107
  grant.m_nBackoffSlots = nBackoffSlots;
108
  m_expectedGrants.push_back (grant);
100
}
109
}
101
void 
110
void 
102
DcfStateTest::DoNotifyAccessGranted (void)
111
DcfStateTest::DoNotifyAccessGranted (void)
 Lines 126-135   DcfManagerTest::NotifyAccessGranted (uin Link Here 
126
  DcfStateTest *state = m_dcfStates[i];
135
  DcfStateTest *state = m_dcfStates[i];
127
  bool result = true;
136
  bool result = true;
128
  NS_TEST_ASSERT (!state->m_expectedGrants.empty ());
137
  NS_TEST_ASSERT (!state->m_expectedGrants.empty ());
129
  std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
138
  struct DcfStateTest::ExpectedGrant expected = state->m_expectedGrants.front ();
130
  state->m_expectedGrants.pop_front ();
139
  state->m_expectedGrants.pop_front ();
131
  NS_TEST_ASSERT_EQUAL (Simulator::Now (), MicroSeconds (expected.second));
140
  NS_TEST_ASSERT_EQUAL (Simulator::Now (), MicroSeconds (expected.m_expectedGrantTime));
132
  m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.first));
141
  m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.m_txTime));
142
  state->StartBackoffNow (expected.m_nBackoffSlots);
133
  if (!result)
143
  if (!result)
134
    {
144
    {
135
      m_result = result;
145
      m_result = result;
 Lines 260-277   DcfManagerTest::AddNavStart (uint64_t at Link Here 
260
                       MicroSeconds (duration));
270
                       MicroSeconds (duration));
261
}
271
}
262
void 
272
void 
263
DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime, 
273
DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime,
264
                                  uint64_t expectedGrantTime, uint32_t from)
274
                                  uint64_t expectedGrantTime, uint32_t nBackoffSlots,
275
                                  uint32_t from)
265
{
276
{
266
  Simulator::Schedule (MicroSeconds (at) - Now (), 
277
  Simulator::Schedule (MicroSeconds (at) - Now (), 
267
                       &DcfManagerTest::DoAccessRequest, this,
278
                       &DcfManagerTest::DoAccessRequest, this,
268
                       txTime, expectedGrantTime, m_dcfStates[from]);
279
                       txTime, expectedGrantTime, nBackoffSlots, m_dcfStates[from]);
269
}
280
}
270
281
271
void
282
void
272
DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state)
283
DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots,
284
                                 DcfStateTest *state)
273
{
285
{
274
  state->QueueTx (txTime, expectedGrantTime);
286
  state->QueueTx (txTime, expectedGrantTime, nBackoffSlots);
275
  m_dcfManager->RequestAccess (state);
287
  m_dcfManager->RequestAccess (state);
276
}
288
}
277
289
 Lines 288-295   DcfManagerTest::RunTests (void) Link Here 
288
  //
300
  //
289
  StartTest (1, 3, 10);
301
  StartTest (1, 3, 10);
290
  AddDcfState (1);
302
  AddDcfState (1);
291
  AddAccessRequest (1, 1, 4, 0);
303
  AddAccessRequest (1, 1, 4, 1, 0);
292
  AddAccessRequest (10, 2, 10, 0);
304
  AddAccessRequest (10, 2, 10, 0, 0);
293
  EndTest ();
305
  EndTest ();
294
306
295
  // The test below mainly intends to test the case where the medium
307
  // The test below mainly intends to test the case where the medium
 Lines 305-311   DcfManagerTest::RunTests (void) Link Here 
305
  AddDcfState (1);
317
  AddDcfState (1);
306
  AddRxOkEvt (20, 40);
318
  AddRxOkEvt (20, 40);
307
  AddRxOkEvt (80, 20);
319
  AddRxOkEvt (80, 20);
308
  AddAccessRequest (30, 2, 118, 0);
320
  AddAccessRequest (30, 2, 118, 4, 0);
309
  ExpectCollision (30, 4, 0); // backoff: 4 slots
321
  ExpectCollision (30, 4, 0); // backoff: 4 slots
310
  EndTest ();
322
  EndTest ();
311
323
 Lines 318-327   DcfManagerTest::RunTests (void) Link Here 
318
  StartTest (4, 6 , 10);
330
  StartTest (4, 6 , 10);
319
  AddDcfState (1);
331
  AddDcfState (1);
320
  AddRxOkEvt (20, 40);
332
  AddRxOkEvt (20, 40);
321
  AddAccessRequest (30, 2, 70, 0);
333
  AddAccessRequest (30, 2, 70, 0, 0);
322
  ExpectCollision (30, 0, 0); // backoff: 0 slots
334
  ExpectCollision (30, 0, 0); // backoff: 0 slots
323
  EndTest ();
335
  EndTest ();
324
336
337
  // Test case where two packets are queued at DcaTxop, the first send starts
338
  // immediately and the second is also immediately indicated but has to wait
339
  // for its backoff.
340
  //
341
  //  20          60     66      70   80
342
  //   | tx        | sifs | aifs  | tx |
343
  //   |20: request access for both packets
344
  StartTest (4, 6 , 10);
345
  AddDcfState (1);
346
  AddAccessRequest (20, 40, 20, 0, 0);
347
  AddAccessRequest (20, 10, 70, 0, 0);
348
  EndTest ();
349
350
  // Test case where two packets are queued at DcaTxop, the first send starts
351
  // immediately and the second is also immediately indicated but has to wait
352
  // for its backoff.
353
  //
354
  //  20          60     66      70        78   88
355
  //   | tx        | sifs | aifs  | backoff | tx |
356
  //   |20: request access for both packets
357
  StartTest (4, 6 , 10);
358
  AddDcfState (1);
359
  AddAccessRequest (20, 40, 20, 2, 0);
360
  AddAccessRequest (20, 10, 78, 0, 0);
361
  EndTest ();
362
325
  // The test below is subject to some discussion because I am 
363
  // The test below is subject to some discussion because I am 
326
  // not sure I understand the intent of the spec here.
364
  // not sure I understand the intent of the spec here.
327
  // i.e., what happens if you make a request to get access
365
  // i.e., what happens if you make a request to get access
 Lines 338-344   DcfManagerTest::RunTests (void) Link Here 
338
  StartTest (4, 6 , 10);
376
  StartTest (4, 6 , 10);
339
  AddDcfState (1);
377
  AddDcfState (1);
340
  AddRxOkEvt (20, 40);
378
  AddRxOkEvt (20, 40);
341
  AddAccessRequest (62, 2, 70, 0);
379
  AddAccessRequest (62, 2, 70, 0, 0);
342
  EndTest ();
380
  EndTest ();
343
381
344
382
 Lines 351-357   DcfManagerTest::RunTests (void) Link Here 
351
  StartTest (4, 6, 10);
389
  StartTest (4, 6, 10);
352
  AddDcfState (1);
390
  AddDcfState (1);
353
  AddRxErrorEvt (20, 40);
391
  AddRxErrorEvt (20, 40);
354
  AddAccessRequest (30, 2, 96, 0);
392
  AddAccessRequest (30, 2, 96, 0, 0);
355
  ExpectCollision (30, 4, 0); // backoff: 4 slots  
393
  ExpectCollision (30, 4, 0); // backoff: 4 slots  
356
  EndTest ();
394
  EndTest ();
357
395
 Lines 364-370   DcfManagerTest::RunTests (void) Link Here 
364
  StartTest (4, 6, 10);
402
  StartTest (4, 6, 10);
365
  AddDcfState (1);
403
  AddDcfState (1);
366
  AddRxErrorEvt (20, 40);
404
  AddRxErrorEvt (20, 40);
367
  AddAccessRequest (30, 2, 101, 0);
405
  AddAccessRequest (30, 2, 101, 0, 0);
368
  ExpectCollision (30, 4, 0); // backoff: 4 slots  
406
  ExpectCollision (30, 4, 0); // backoff: 4 slots  
369
  AddRxOkEvt (69, 6);
407
  AddRxOkEvt (69, 6);
370
  EndTest ();
408
  EndTest ();
 Lines 381-390   DcfManagerTest::RunTests (void) Link Here 
381
  AddDcfState (1); // high priority DCF
419
  AddDcfState (1); // high priority DCF
382
  AddDcfState (3); // low priority DCF
420
  AddDcfState (3); // low priority DCF
383
  AddRxOkEvt (20, 40);
421
  AddRxOkEvt (20, 40);
384
  AddAccessRequest (30, 10, 78, 0);
422
  AddAccessRequest (30, 10, 78, 0, 0);
385
  ExpectCollision (30, 2, 0); // backoff: 2 slot
423
  ExpectCollision (30, 2, 0); // backoff: 2 slot
386
424
387
  AddAccessRequest (40, 2, 110, 1);
425
  AddAccessRequest (40, 2, 110, 0, 1);
388
  ExpectCollision (40, 0, 1); // backoff: 0 slot
426
  ExpectCollision (40, 0, 1); // backoff: 0 slot
389
  ExpectInternalCollision (78, 1, 1); // backoff: 1 slot
427
  ExpectInternalCollision (78, 1, 1); // backoff: 1 slot
390
  EndTest ();
428
  EndTest ();
 Lines 401-407   DcfManagerTest::RunTests (void) Link Here 
401
  AddNavStart (60, 15);
439
  AddNavStart (60, 15);
402
  AddRxOkEvt (66, 5);
440
  AddRxOkEvt (66, 5);
403
  AddNavStart (71, 0);
441
  AddNavStart (71, 0);
404
  AddAccessRequest (30, 10, 93, 0);
442
  AddAccessRequest (30, 10, 93, 0, 0);
405
  ExpectCollision (30, 2, 0); // backoff: 2 slot
443
  ExpectCollision (30, 2, 0); // backoff: 2 slot
406
  EndTest ();
444
  EndTest ();
407
445
 Lines 417-423   DcfManagerTest::RunTests (void) Link Here 
417
  AddNavStart (60, 15);
455
  AddNavStart (60, 15);
418
  AddRxOkEvt (66, 5);
456
  AddRxOkEvt (66, 5);
419
  AddNavReset (71, 2);
457
  AddNavReset (71, 2);
420
  AddAccessRequest (30, 10, 91, 0);
458
  AddAccessRequest (30, 10, 91, 0, 0);
421
  ExpectCollision (30, 2, 0); // backoff: 2 slot
459
  ExpectCollision (30, 2, 0); // backoff: 2 slot
422
  EndTest ();
460
  EndTest ();
423
461
 Lines 425-431   DcfManagerTest::RunTests (void) Link Here 
425
  StartTest (4, 6, 10);
463
  StartTest (4, 6, 10);
426
  AddDcfState (2);
464
  AddDcfState (2);
427
  AddRxOkEvt (20, 40);
465
  AddRxOkEvt (20, 40);
428
  AddAccessRequest (80, 10, 80, 0);
466
  AddAccessRequest (80, 10, 80, 0, 0);
429
  EndTest ();
467
  EndTest ();
430
468
431
469
 Lines 433-442   DcfManagerTest::RunTests (void) Link Here 
433
  AddDcfState (2);
471
  AddDcfState (2);
434
  AddRxOkEvt (20, 40);
472
  AddRxOkEvt (20, 40);
435
  AddRxOkEvt (78, 8);
473
  AddRxOkEvt (78, 8);
436
  AddAccessRequest (30, 50, 108, 0);
474
  AddAccessRequest (30, 50, 108, 0, 0);
437
  ExpectCollision (30, 3, 0); // backoff: 3 slots
475
  ExpectCollision (30, 3, 0); // backoff: 3 slots
438
  EndTest ();
476
  EndTest ();
439
 
440
477
441
  return m_result;
478
  return m_result;
442
}
479
}
(-)a/src/devices/wifi/dcf-manager.cc (-2 / +12 lines)
 Lines 42-47   namespace ns3 { Link Here 
42
DcfState::DcfState ()
42
DcfState::DcfState ()
43
  : m_backoffSlots (0),
43
  : m_backoffSlots (0),
44
    m_backoffStart (Seconds (0.0)),
44
    m_backoffStart (Seconds (0.0)),
45
    m_backoffElapsed (true),
45
    m_cwMin (0),
46
    m_cwMin (0),
46
    m_cwMax (0),
47
    m_cwMax (0),
47
    m_cw (0),
48
    m_cw (0),
 Lines 101-106   DcfState::UpdateBackoffSlotsNow (uint32_ Link Here 
101
  m_backoffSlots -= nSlots;
102
  m_backoffSlots -= nSlots;
102
  m_backoffStart = backoffUpdateBound;
103
  m_backoffStart = backoffUpdateBound;
103
  MY_DEBUG ("update slots="<<nSlots<<" slots, backoff="<<m_backoffSlots);
104
  MY_DEBUG ("update slots="<<nSlots<<" slots, backoff="<<m_backoffSlots);
105
  if (m_backoffSlots == 0)
106
    {
107
      m_backoffElapsed = true;
108
    }
104
}
109
}
105
110
106
void 
111
void 
 Lines 110-115   DcfState::StartBackoffNow (uint32_t nSlo Link Here 
110
  MY_DEBUG ("start backoff="<<nSlots<<" slots");
115
  MY_DEBUG ("start backoff="<<nSlots<<" slots");
111
  m_backoffSlots = nSlots;
116
  m_backoffSlots = nSlots;
112
  m_backoffStart = Simulator::Now ();
117
  m_backoffStart = Simulator::Now ();
118
  m_backoffElapsed = false;
113
}
119
}
114
120
115
uint32_t
121
uint32_t
 Lines 127-132   DcfState::GetBackoffStart (void) const Link Here 
127
{
133
{
128
  return m_backoffStart;
134
  return m_backoffStart;
129
}
135
}
136
bool
137
DcfState::IsBackoffElapsed (void) const
138
{
139
  return m_backoffElapsed;
140
}
130
bool 
141
bool 
131
DcfState::IsAccessRequested (void) const
142
DcfState::IsAccessRequested (void) const
132
{
143
{
 Lines 323-330   DcfManager::RequestAccess (DcfState *sta Link Here 
323
   * If there is a collision, generate a backoff
334
   * If there is a collision, generate a backoff
324
   * by notifying the collision to the user.
335
   * by notifying the collision to the user.
325
   */
336
   */
326
  if (state->GetBackoffSlots () == 0 && 
337
  if (state->IsBackoffElapsed() && IsBusy ())
327
      IsBusy ())
328
    {
338
    {
329
      MY_DEBUG ("medium is busy: collision");
339
      MY_DEBUG ("medium is busy: collision");
330
      /* someone else has accessed the medium.
340
      /* someone else has accessed the medium.
(-)a/src/devices/wifi/dcf-manager.h (+5 lines)
 Lines 59-64   public: Link Here 
59
   */
59
   */
60
  void StartBackoffNow (uint32_t nSlots);
60
  void StartBackoffNow (uint32_t nSlots);
61
  /**
61
  /**
62
   * Returns true if the backoff procedure elapsed.
63
   */
64
  bool IsBackoffElapsed (void) const; 
65
  /**
62
   * \returns the current value of the CW variable. The initial value is
66
   * \returns the current value of the CW variable. The initial value is
63
   * minCW.
67
   * minCW.
64
   */
68
   */
 Lines 116-121   private: Link Here 
116
  // time at which a backoff was started or the time at which
120
  // time at which a backoff was started or the time at which
117
  // the backoff counter was last updated.
121
  // the backoff counter was last updated.
118
  Time m_backoffStart;
122
  Time m_backoffStart;
123
  bool m_backoffElapsed;
119
  uint32_t m_cwMin;
124
  uint32_t m_cwMin;
120
  uint32_t m_cwMax;
125
  uint32_t m_cwMax;
121
  uint32_t m_cw;
126
  uint32_t m_cw;

Return to bug 555