# HG changeset patch # User Timo Bingmann # Date 1242054474 -7200 # Node ID fdeb02bd7cb3cd1f88460283fa57246ffc944949 # Parent 9491c5faaec6b6560dfe224a4f5756f01195c78f Correction of DCF collision detection time. diff -r 9491c5faaec6 -r fdeb02bd7cb3 src/devices/wifi/dcf-manager-test.cc --- a/src/devices/wifi/dcf-manager-test.cc Thu May 07 09:13:06 2009 +0200 +++ b/src/devices/wifi/dcf-manager-test.cc Mon May 11 17:07:54 2009 +0200 @@ -32,15 +32,20 @@ class DcfStateTest : public DcfState { public: DcfStateTest (DcfManagerTest *test, uint32_t i); - void QueueTx (uint64_t txTime, uint64_t expectedGrantTime); + void QueueTx (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots); private: friend class DcfManagerTest; virtual void DoNotifyAccessGranted (void); virtual void DoNotifyInternalCollision (void); virtual void DoNotifyCollision (void); - typedef std::pair ExpectedGrant; - typedef std::list ExpectedGrants; + struct ExpectedGrant { + uint64_t m_txTime; + uint64_t m_expectedGrantTime; + uint32_t m_nBackoffSlots; + }; + typedef std::list ExpectedGrants; + struct ExpectedCollision { uint64_t at; uint32_t nSlots; @@ -77,9 +82,9 @@ private: void AddRxErrorEvt (uint64_t at, uint64_t duration); void AddNavReset (uint64_t at, uint64_t duration); void AddNavStart (uint64_t at, uint64_t duration); - void AddAccessRequest (uint64_t at, uint64_t txTime, - uint64_t expectedGrantTime, uint32_t from); - void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state); + void AddAccessRequest (uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, + uint32_t nBackoffSlots, uint32_t from); + void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots, DcfStateTest *state); typedef std::vector DcfStates; @@ -94,9 +99,13 @@ DcfStateTest::DcfStateTest (DcfManagerTe : m_test (test), m_i(i) {} void -DcfStateTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime) +DcfStateTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots) { - m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime)); + struct ExpectedGrant grant; + grant.m_txTime = txTime; + grant.m_expectedGrantTime = expectedGrantTime; + grant.m_nBackoffSlots = nBackoffSlots; + m_expectedGrants.push_back (grant); } void DcfStateTest::DoNotifyAccessGranted (void) @@ -126,10 +135,11 @@ DcfManagerTest::NotifyAccessGranted (uin DcfStateTest *state = m_dcfStates[i]; bool result = true; NS_TEST_ASSERT (!state->m_expectedGrants.empty ()); - std::pair expected = state->m_expectedGrants.front (); + struct DcfStateTest::ExpectedGrant expected = state->m_expectedGrants.front (); state->m_expectedGrants.pop_front (); - NS_TEST_ASSERT_EQUAL (Simulator::Now (), MicroSeconds (expected.second)); - m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.first)); + NS_TEST_ASSERT_EQUAL (Simulator::Now (), MicroSeconds (expected.m_expectedGrantTime)); + m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.m_txTime)); + state->StartBackoffNow (expected.m_nBackoffSlots); if (!result) { m_result = result; @@ -260,18 +270,20 @@ DcfManagerTest::AddNavStart (uint64_t at MicroSeconds (duration)); } void -DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime, - uint64_t expectedGrantTime, uint32_t from) +DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime, + uint64_t expectedGrantTime, uint32_t nBackoffSlots, + uint32_t from) { Simulator::Schedule (MicroSeconds (at) - Now (), &DcfManagerTest::DoAccessRequest, this, - txTime, expectedGrantTime, m_dcfStates[from]); + txTime, expectedGrantTime, nBackoffSlots, m_dcfStates[from]); } void -DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state) +DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, uint32_t nBackoffSlots, + DcfStateTest *state) { - state->QueueTx (txTime, expectedGrantTime); + state->QueueTx (txTime, expectedGrantTime, nBackoffSlots); m_dcfManager->RequestAccess (state); } @@ -288,8 +300,8 @@ DcfManagerTest::RunTests (void) // StartTest (1, 3, 10); AddDcfState (1); - AddAccessRequest (1, 1, 4, 0); - AddAccessRequest (10, 2, 10, 0); + AddAccessRequest (1, 1, 4, 1, 0); + AddAccessRequest (10, 2, 10, 0, 0); EndTest (); // The test below mainly intends to test the case where the medium @@ -305,7 +317,7 @@ DcfManagerTest::RunTests (void) AddDcfState (1); AddRxOkEvt (20, 40); AddRxOkEvt (80, 20); - AddAccessRequest (30, 2, 118, 0); + AddAccessRequest (30, 2, 118, 4, 0); ExpectCollision (30, 4, 0); // backoff: 4 slots EndTest (); @@ -318,10 +330,36 @@ DcfManagerTest::RunTests (void) StartTest (4, 6 , 10); AddDcfState (1); AddRxOkEvt (20, 40); - AddAccessRequest (30, 2, 70, 0); + AddAccessRequest (30, 2, 70, 0, 0); ExpectCollision (30, 0, 0); // backoff: 0 slots EndTest (); + // Test case where two packets are queued at DcaTxop, the first send starts + // immediately and the second is also immediately indicated but has to wait + // for its backoff. + // + // 20 60 66 70 80 + // | tx | sifs | aifs | tx | + // |20: request access for both packets + StartTest (4, 6 , 10); + AddDcfState (1); + AddAccessRequest (20, 40, 20, 0, 0); + AddAccessRequest (20, 10, 70, 0, 0); + EndTest (); + + // Test case where two packets are queued at DcaTxop, the first send starts + // immediately and the second is also immediately indicated but has to wait + // for its backoff. + // + // 20 60 66 70 78 88 + // | tx | sifs | aifs | backoff | tx | + // |20: request access for both packets + StartTest (4, 6 , 10); + AddDcfState (1); + AddAccessRequest (20, 40, 20, 2, 0); + AddAccessRequest (20, 10, 78, 0, 0); + EndTest (); + // The test below is subject to some discussion because I am // not sure I understand the intent of the spec here. // i.e., what happens if you make a request to get access @@ -338,7 +376,7 @@ DcfManagerTest::RunTests (void) StartTest (4, 6 , 10); AddDcfState (1); AddRxOkEvt (20, 40); - AddAccessRequest (62, 2, 70, 0); + AddAccessRequest (62, 2, 70, 0, 0); EndTest (); @@ -351,7 +389,7 @@ DcfManagerTest::RunTests (void) StartTest (4, 6, 10); AddDcfState (1); AddRxErrorEvt (20, 40); - AddAccessRequest (30, 2, 96, 0); + AddAccessRequest (30, 2, 96, 0, 0); ExpectCollision (30, 4, 0); // backoff: 4 slots EndTest (); @@ -364,7 +402,7 @@ DcfManagerTest::RunTests (void) StartTest (4, 6, 10); AddDcfState (1); AddRxErrorEvt (20, 40); - AddAccessRequest (30, 2, 101, 0); + AddAccessRequest (30, 2, 101, 0, 0); ExpectCollision (30, 4, 0); // backoff: 4 slots AddRxOkEvt (69, 6); EndTest (); @@ -381,10 +419,10 @@ DcfManagerTest::RunTests (void) AddDcfState (1); // high priority DCF AddDcfState (3); // low priority DCF AddRxOkEvt (20, 40); - AddAccessRequest (30, 10, 78, 0); + AddAccessRequest (30, 10, 78, 0, 0); ExpectCollision (30, 2, 0); // backoff: 2 slot - AddAccessRequest (40, 2, 110, 1); + AddAccessRequest (40, 2, 110, 0, 1); ExpectCollision (40, 0, 1); // backoff: 0 slot ExpectInternalCollision (78, 1, 1); // backoff: 1 slot EndTest (); @@ -401,7 +439,7 @@ DcfManagerTest::RunTests (void) AddNavStart (60, 15); AddRxOkEvt (66, 5); AddNavStart (71, 0); - AddAccessRequest (30, 10, 93, 0); + AddAccessRequest (30, 10, 93, 0, 0); ExpectCollision (30, 2, 0); // backoff: 2 slot EndTest (); @@ -417,7 +455,7 @@ DcfManagerTest::RunTests (void) AddNavStart (60, 15); AddRxOkEvt (66, 5); AddNavReset (71, 2); - AddAccessRequest (30, 10, 91, 0); + AddAccessRequest (30, 10, 91, 0, 0); ExpectCollision (30, 2, 0); // backoff: 2 slot EndTest (); @@ -425,7 +463,7 @@ DcfManagerTest::RunTests (void) StartTest (4, 6, 10); AddDcfState (2); AddRxOkEvt (20, 40); - AddAccessRequest (80, 10, 80, 0); + AddAccessRequest (80, 10, 80, 0, 0); EndTest (); @@ -433,10 +471,9 @@ DcfManagerTest::RunTests (void) AddDcfState (2); AddRxOkEvt (20, 40); AddRxOkEvt (78, 8); - AddAccessRequest (30, 50, 108, 0); + AddAccessRequest (30, 50, 108, 0, 0); ExpectCollision (30, 3, 0); // backoff: 3 slots EndTest (); - return m_result; } diff -r 9491c5faaec6 -r fdeb02bd7cb3 src/devices/wifi/dcf-manager.cc --- a/src/devices/wifi/dcf-manager.cc Thu May 07 09:13:06 2009 +0200 +++ b/src/devices/wifi/dcf-manager.cc Mon May 11 17:07:54 2009 +0200 @@ -42,6 +42,7 @@ namespace ns3 { DcfState::DcfState () : m_backoffSlots (0), m_backoffStart (Seconds (0.0)), + m_backoffElapsed (true), m_cwMin (0), m_cwMax (0), m_cw (0), @@ -101,6 +102,10 @@ DcfState::UpdateBackoffSlotsNow (uint32_ m_backoffSlots -= nSlots; m_backoffStart = backoffUpdateBound; MY_DEBUG ("update slots="<GetBackoffSlots () == 0 && - IsBusy ()) + if (state->IsBackoffElapsed() && IsBusy ()) { MY_DEBUG ("medium is busy: collision"); /* someone else has accessed the medium. diff -r 9491c5faaec6 -r fdeb02bd7cb3 src/devices/wifi/dcf-manager.h --- a/src/devices/wifi/dcf-manager.h Thu May 07 09:13:06 2009 +0200 +++ b/src/devices/wifi/dcf-manager.h Mon May 11 17:07:54 2009 +0200 @@ -59,6 +59,10 @@ public: */ void StartBackoffNow (uint32_t nSlots); /** + * Returns true if the backoff procedure elapsed. + */ + bool IsBackoffElapsed (void) const; + /** * \returns the current value of the CW variable. The initial value is * minCW. */ @@ -116,6 +120,7 @@ private: // time at which a backoff was started or the time at which // the backoff counter was last updated. Time m_backoffStart; + bool m_backoffElapsed; uint32_t m_cwMin; uint32_t m_cwMax; uint32_t m_cw;