bug 595: PHY may start receive packet inside SIFS
authorKirill V. Andreev <kirillano@yandex.ru>
Thu, 25 Jun 2009 15:25:10 +0200
changeset 4598 9b07308116ed
parent 4594 14ce84fd7ae3
child 4599 1eaba8e55c8f
bug 595: PHY may start receive packet inside SIFS
src/devices/wifi/dcf-manager-test.cc
src/devices/wifi/dcf-manager.cc
--- a/src/devices/wifi/dcf-manager-test.cc	Thu Jun 25 14:15:27 2009 +0200
+++ b/src/devices/wifi/dcf-manager-test.cc	Thu Jun 25 15:25:10 2009 +0200
@@ -75,6 +75,8 @@
   void ExpectCollision (uint64_t time, uint32_t from, uint32_t nSlots);
   void AddRxOkEvt (uint64_t at, uint64_t duration);
   void AddRxErrorEvt (uint64_t at, uint64_t duration);
+  void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
+  void AddTxEvt (uint64_t at, uint64_t duration);
   void AddNavReset (uint64_t at, uint64_t duration);
   void AddNavStart (uint64_t at, uint64_t duration);
   void AddAckTimeoutReset (uint64_t at);
@@ -143,6 +145,13 @@
       m_result = result;
     }
 }
+void
+DcfManagerTest::AddTxEvt (uint64_t at, uint64_t duration)
+{
+  Simulator::Schedule (MicroSeconds (at) - Now (), 
+                       &DcfManager::NotifyTxStartNow, m_dcfManager, 
+                       MicroSeconds (duration));
+}
 void 
 DcfManagerTest::NotifyInternalCollision (uint32_t i)
 {
@@ -244,6 +253,13 @@
   Simulator::Schedule (MicroSeconds (at+duration) - Now (), 
                        &DcfManager::NotifyRxEndOkNow, m_dcfManager);
 }
+void
+DcfManagerTest::AddRxInsideSifsEvt (uint64_t at, uint64_t duration)
+{
+  Simulator::Schedule (MicroSeconds (at) - Now (), 
+                       &DcfManager::NotifyRxStartNow, m_dcfManager, 
+                       MicroSeconds (duration));
+}
 void 
 DcfManagerTest::AddRxErrorEvt (uint64_t at, uint64_t duration)
 {
@@ -321,6 +337,18 @@
   AddAccessRequest (1, 1, 4, 0);
   AddAccessRequest (10, 2, 10, 0);
   EndTest ();
+  // Check that receiving inside SIFS shall be cancelled properly:
+  //  0      3       4    5      8     9     12       13 14
+  //  | sifs | aifsn | tx | sifs | ack | sifs | aifsn |  |tx | 
+  //
+  StartTest (1, 3, 10);
+  AddDcfState (1);
+  AddAccessRequest (1, 1, 4, 0);
+  AddRxInsideSifsEvt (6, 10);
+  AddTxEvt(8, 1);
+  AddAccessRequest (14, 2, 14, 0);
+  EndTest ();
+
 
   // The test below mainly intends to test the case where the medium
   // becomes busy in the middle of a backoff slot: the backoff counter
--- a/src/devices/wifi/dcf-manager.cc	Thu Jun 25 14:15:27 2009 +0200
+++ b/src/devices/wifi/dcf-manager.cc	Thu Jun 25 15:25:10 2009 +0200
@@ -572,6 +572,17 @@
 void 
 DcfManager::NotifyTxStartNow (Time duration)
 {
+  if (m_rxing)
+  {
+    //this may be caused only if PHY has started to receive a packet
+    //inside SIFS, so, we check that lastRxStart was maximum a SIFS
+    //ago
+    NS_ASSERT(Simulator::Now () - m_lastRxStart < m_sifs);
+    m_lastRxEnd = Simulator::Now ();
+    m_lastRxDuration = m_lastRxEnd - m_lastRxStart;
+    m_lastRxReceivedOk = true;
+    m_rxing = false;
+  }
   MY_DEBUG ("tx start for "<<duration);
   UpdateBackoff ();
   m_lastTxStart = Simulator::Now ();