Merge changes from ns-3-dev.

This commit is contained in:
Andrey Mazo
2009-06-08 16:30:52 +04:00
7 changed files with 145 additions and 12 deletions

View File

@@ -68,7 +68,7 @@ public:
private:
void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs);
void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
void AddDcfState (uint32_t aifsn);
void EndTest (void);
void ExpectInternalCollision (uint64_t time, uint32_t from, uint32_t nSlots);
@@ -77,14 +77,21 @@ 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 AddAckTimeoutReset (uint64_t at);
void AddAccessRequest (uint64_t at, uint64_t txTime,
uint64_t expectedGrantTime, uint32_t from);
void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
uint64_t expectedGrantTime, uint32_t from);
///\param ackDelay is delay of the ack after txEnd
void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
void DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state);
typedef std::vector<DcfStateTest *> DcfStates;
DcfManager *m_dcfManager;
DcfStates m_dcfStates;
uint32_t m_ackTimeoutValue;
bool m_result;
};
@@ -130,6 +137,7 @@ DcfManagerTest::NotifyAccessGranted (uint32_t i)
state->m_expectedGrants.pop_front ();
NS_TEST_ASSERT_EQUAL (Simulator::Now (), MicroSeconds (expected.second));
m_dcfManager->NotifyTxStartNow (MicroSeconds (expected.first));
m_dcfManager->NotifyAckTimeoutStartNow (MicroSeconds (m_ackTimeoutValue + expected.first));
if (!result)
{
m_result = result;
@@ -187,12 +195,13 @@ DcfManagerTest::ExpectCollision (uint64_t time, uint32_t nSlots, uint32_t from)
}
void
DcfManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs)
DcfManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue)
{
m_dcfManager = new DcfManager ();
m_dcfManager->SetSlot (MicroSeconds (slotTime));
m_dcfManager->SetSifs (MicroSeconds (sifs));
m_dcfManager->SetEifsNoDifs (MicroSeconds (eifsNoDifsNoSifs+sifs));
m_ackTimeoutValue = ackTimeoutValue;
}
void
@@ -260,14 +269,35 @@ DcfManagerTest::AddNavStart (uint64_t at, uint64_t duration)
MicroSeconds (duration));
}
void
DcfManagerTest::AddAckTimeoutReset (uint64_t at)
{
Simulator::Schedule (MicroSeconds (at) - Now (),
&DcfManager::NotifyAckTimeoutResetNow, m_dcfManager);
}
void
DcfManagerTest::AddAccessRequest (uint64_t at, uint64_t txTime,
uint64_t expectedGrantTime, uint32_t from)
{
AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
}
void
DcfManagerTest::AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
uint64_t expectedGrantTime, uint32_t from)
{
Simulator::Schedule (MicroSeconds (at) - Now (),
&DcfManagerTest::DoAccessRequest, this,
txTime, expectedGrantTime, m_dcfStates[from]);
}
void
DcfManagerTest::AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
{
NS_ASSERT(ackDelay < m_ackTimeoutValue);
Simulator::Schedule (MicroSeconds (at) - Now (),
&DcfManagerTest::DoAccessRequest, this,
txTime, expectedGrantTime, m_dcfStates[from]);
AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
}
void
DcfManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, DcfStateTest *state)
{
@@ -301,7 +331,7 @@ DcfManagerTest::RunTests (void)
// | rx | sifs | aifsn | bslot0 | bslot1 | | rx | sifs | aifsn | bslot2 | bslot3 | tx |
// |
// 30 request access. backoff slots: 4
StartTest (4, 6 , 10);
StartTest (4, 6, 10);
AddDcfState (1);
AddRxOkEvt (20, 40);
AddRxOkEvt (80, 20);
@@ -388,7 +418,58 @@ DcfManagerTest::RunTests (void)
ExpectCollision (40, 0, 1); // backoff: 0 slot
ExpectInternalCollision (78, 1, 1); // backoff: 1 slot
EndTest ();
// Test of AckTimeout handling: First queue requests access and ack procedure fails,
// inside the ack timeout second queue with higher priority requests access.
//
// 20 40 50 60 66 76
// DCF0 - low | tx | ack timeout |sifs| |
// DCF1 - high | | |sifs| tx |
// ^ request access
StartTest (4, 6, 10);
AddDcfState (2); // high priority DCF
AddDcfState (0); // low priority DCF
AddAccessRequestWithAckTimeout (20, 20, 20, 0);
AddAccessRequest (50, 10, 66, 1);
EndTest ();
// Test of AckTimeout handling:
//
// First queue requests access and ack is 2 us delayed (got ack interval at the picture),
// inside this interval second queue with higher priority requests access.
//
// 20 40 41 42 48 58
// DCF0 - low | tx |got ack |sifs| |
// DCF1 - high | | |sifs| tx |
// ^ request access
StartTest (4, 6, 10);
AddDcfState (2); // high priority DCF
AddDcfState (0); // low priority DCF
AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
AddAccessRequest (41, 10, 48, 1);
EndTest ();
//Repeat the same but with one queue:
// 20 40 41 42 48 58
// DCF0 - low | tx |got ack |sifs| |
// ^ request access
StartTest (4, 6, 10);
AddDcfState (2);
AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
AddAccessRequest (41, 10, 56, 0);
EndTest ();
//Repeat the same when ack was delayed:
//and request the next access before previous tx end:
// 20 39 40 42 64 74
// DCF0 - low | tx |got ack |sifs + 4 * slot| |
// ^ request access
StartTest (4, 6, 10);
AddDcfState (2);
AddAccessRequestWithSuccessfullAck (20, 20, 20, 2, 0);
AddAccessRequest (39, 10, 64, 0);
ExpectCollision (39, 2, 0); // backoff: 2 slot
EndTest ();
//
// test simple NAV count. This scenario modelizes a simple DATA+ACK handshake
@@ -405,7 +486,6 @@ DcfManagerTest::RunTests (void)
ExpectCollision (30, 2, 0); // backoff: 2 slot
EndTest ();
//
// test more complex NAV handling by a CF-poll. This scenario modelizes a
// simple DATA+ACK handshake interrupted by a CF-poll which resets the

View File

@@ -375,7 +375,7 @@ DcfManager::DoGrantAccess (void)
{
DcfState *state = *i;
if (state->IsAccessRequested () &&
GetBackoffEndFor (state).GetTimeStep() <= Simulator::Now ().GetTimeStep ())
GetBackoffEndFor (state) <= Simulator::Now () )
{
/**
* This is the first dcf we find with an expired backoff and which
@@ -452,12 +452,14 @@ DcfManager::GetAccessGrantStart (void) const
Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs;
Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs;
Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs;
Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs;
Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs;
Time accessGrantedStart = MostRecent (rxAccessStart,
busyAccessStart,
txAccessStart,
navAccessStart,
m_lastAckTimeoutEnd,
m_lastCtsTimeoutEnd
ackTimeoutAccessStart,
ctsTimeoutAccessStart
);
NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
", rx access start=" << rxAccessStart <<
@@ -617,6 +619,7 @@ DcfManager::NotifyNavStartNow (Time duration)
void
DcfManager::NotifyAckTimeoutStartNow (Time duration)
{
NS_ASSERT(m_lastAckTimeoutEnd < Simulator::Now ());
m_lastAckTimeoutEnd = Simulator::Now () + duration;
}
void

View File

@@ -1,4 +1,25 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef DCF_MANAGER_H
#define DCF_MANAGER_H
#include "ns3/nstime.h"
#include "ns3/event-id.h"
@@ -242,7 +263,6 @@ public:
void NotifyAckTimeoutResetNow ();
void NotifyCtsTimeoutStartNow (Time duration);
void NotifyCtsTimeoutResetNow ();
void NotifyAckTimeoutEnd (Time duration);
private:
void UpdateBackoff (void);
Time MostRecent (Time a, Time b) const;
@@ -290,3 +310,5 @@ private:
};
} // namespace ns3
#endif /* DCF_MANAGER_H */

View File

@@ -805,7 +805,7 @@ MacLow::DoNavResetNow (Time duration)
(*i)->NavReset (duration);
}
m_lastNavStart = Simulator::Now ();
m_lastNavStart = duration;
m_lastNavDuration = duration;
}
bool
MacLow::DoNavStartNow (Time duration)

View File

@@ -63,7 +63,7 @@ WifiMac::GetDefaultCtsAckTimeout (void)
*/
Time ctsTimeout = GetDefaultSifs ();
ctsTimeout += GetDefaultCtsAckDelay ();
ctsTimeout += GetDefaultMaxPropagationDelay () * Scalar (2);
ctsTimeout += MicroSeconds (GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2);
ctsTimeout += GetDefaultSlot ();
return ctsTimeout;
}

View File

@@ -292,7 +292,19 @@ Simulator::GetMaximumSimulationTime (void)
void
Simulator::SetImplementation (Ptr<SimulatorImpl> impl)
{
NS_FATAL_ERROR ("TODO");
if (PeekImpl () != 0)
{
NS_FATAL_ERROR ("It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
}
*PeekImpl () = impl;
//
// Note: we call LogSetTimePrinter _after_ creating the implementation
// object because the act of creation can trigger calls to the logging
// framework which would call the TimePrinter function which would call
// Simulator::Now which would call Simulator::GetImpl, and, thus, get us
// in an infinite recursion until the stack explodes.
//
LogSetTimePrinter (&TimePrinter);
}
Ptr<SimulatorImpl>
Simulator::GetImplementation (void)

View File

@@ -4,6 +4,8 @@
#include "ns3/object-vector.h"
#include "ns3/config.h"
#include "ns3/log.h"
#include "ns3/global-value.h"
#include "ns3/string.h"
#include "ns3/helper-module.h"
using namespace ns3;
@@ -365,5 +367,19 @@ int main (int argc, char *argv[])
std::cout << "/*!" << std::endl
<< "\\ingroup core" << std::endl
<< "\\defgroup GlobalValueList The list of all global values." << std::endl
<< "<ul>" << std::endl;
for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i)
{
StringValue val;
(*i)->GetValue (val);
std::cout << " <li><b>" << (*i)->GetName () << "</b>: " << (*i)->GetHelp () << "(" << val.Get () << ")</li>" << std::endl;
}
std::cout << "</ul>" << std::endl
<< "*/" << std::endl;
return 0;
}