Add BurstErrorModel class
This commit is contained in:
@@ -57,16 +57,21 @@ main (int argc, char *argv[])
|
||||
|
||||
|
||||
// Set a few attributes
|
||||
Config::SetDefault ("ns3::RateErrorModel::ErrorRate", DoubleValue (0.01));
|
||||
Config::SetDefault ("ns3::RateErrorModel::ErrorRate", DoubleValue (0.001));
|
||||
Config::SetDefault ("ns3::RateErrorModel::ErrorUnit", StringValue ("ERROR_UNIT_PACKET"));
|
||||
|
||||
Config::SetDefault ("ns3::BurstErrorModel::ErrorRate", DoubleValue (0.01));
|
||||
Config::SetDefault ("ns3::BurstErrorModel::BurstSize", StringValue ("ns3::UniformRandomVariable[Min=1|Max=3]"));
|
||||
|
||||
Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
|
||||
Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRateValue (DataRate ("448kb/s")));
|
||||
|
||||
std::string errorModelType = "ns3::RateErrorModel";
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// Bind()s at run-time, via command-line arguments
|
||||
CommandLine cmd;
|
||||
cmd.AddValue("errorModelType", "TypeId of the error model to use", errorModelType);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
// Here, we will explicitly create four nodes. In more sophisticated
|
||||
@@ -146,9 +151,11 @@ main (int argc, char *argv[])
|
||||
// Error model
|
||||
//
|
||||
// Create an ErrorModel based on the implementation (constructor)
|
||||
// specified by the default classId
|
||||
Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ();
|
||||
em->SetAttribute ("ErrorRate", DoubleValue (0.001));
|
||||
// specified by the default TypeId
|
||||
|
||||
ObjectFactory factory;
|
||||
factory.SetTypeId (errorModelType);
|
||||
Ptr<ErrorModel> em = factory.Create<ErrorModel> ();
|
||||
d3d2.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
|
||||
|
||||
// Now, let's use the ListErrorModel and explicitly force a loss
|
||||
|
||||
@@ -134,3 +134,20 @@ The ``error-model`` unit test suite provides a single test case of
|
||||
of a particular combination of ErrorRate and ErrorUnit for the
|
||||
``RateErrorModel`` applied to a ``SimpleNetDevice``.
|
||||
|
||||
Acknowledgements
|
||||
****************
|
||||
|
||||
The basic ErrorModel, RateErrorModel, and ListErrorModel classes were ported
|
||||
from |ns2| to |ns3| in 2007. The ReceiveListErrorModel was added at that
|
||||
time.
|
||||
|
||||
The burst error model is due to Truc Anh N. Nguyen at the University of
|
||||
Kansas (James P.G. Sterbenz <jpgs@ittc.ku.edu>, director, ResiliNets
|
||||
Research Group (http://wiki.ittc.ku.edu/resilinets), Information and
|
||||
Telecommunication Technology Center (ITTC) and Department of Electrical
|
||||
Engineering and Computer Science, The University of Kansas Lawrence, KS USA).
|
||||
Work supported in part by NSF FIND (Future Internet Design) Program
|
||||
under grant CNS-0626918 (Postmodern Internet Architecture),
|
||||
NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and
|
||||
Experimentation on GENI), US Department of Defense (DoD), and ITTC at
|
||||
The University of Kansas.
|
||||
|
||||
@@ -1,4 +1,29 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* BurstErrorModel additions
|
||||
*
|
||||
* Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
|
||||
* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
|
||||
* James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
|
||||
*/
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/simple-net-device.h"
|
||||
@@ -117,6 +142,85 @@ ErrorModelSimple::DoRun (void)
|
||||
NS_TEST_ASSERT_MSG_EQ (m_drops, 9, "Wrong number of drops.");
|
||||
}
|
||||
|
||||
class BurstErrorModelSimple : public TestCase
|
||||
{
|
||||
public:
|
||||
BurstErrorModelSimple ();
|
||||
virtual ~BurstErrorModelSimple ();
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
bool Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
|
||||
void DropEvent (Ptr<const Packet> p);
|
||||
uint32_t m_count;
|
||||
uint32_t m_drops;
|
||||
};
|
||||
|
||||
// Add some help text to this case to describe what it is intended to test
|
||||
BurstErrorModelSimple::BurstErrorModelSimple ()
|
||||
: TestCase ("ErrorModel and PhyRxDrop trace for SimpleNetDevice"), m_count (0), m_drops (0)
|
||||
{
|
||||
}
|
||||
|
||||
BurstErrorModelSimple::~BurstErrorModelSimple ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
BurstErrorModelSimple::Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr)
|
||||
{
|
||||
m_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BurstErrorModelSimple::DropEvent (Ptr<const Packet> p)
|
||||
{
|
||||
m_drops++;
|
||||
}
|
||||
|
||||
void
|
||||
BurstErrorModelSimple::DoRun (void)
|
||||
{
|
||||
// Set some arbitrary deterministic values
|
||||
RngSeedManager::SetSeed (5);
|
||||
RngSeedManager::SetRun (8);
|
||||
|
||||
Ptr<Node> a = CreateObject<Node> ();
|
||||
Ptr<Node> b = CreateObject<Node> ();
|
||||
|
||||
Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice> ();
|
||||
Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice> ();
|
||||
Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
|
||||
BuildSimpleTopology (a, b, input, output, channel);
|
||||
|
||||
output->SetReceiveCallback (MakeCallback (&BurstErrorModelSimple::Receive, this));
|
||||
Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable> ();
|
||||
// Set this variable to a specific stream
|
||||
uv->SetStream (50);
|
||||
|
||||
Ptr<BurstErrorModel> em = CreateObject<BurstErrorModel> ();
|
||||
em->SetRandomVariable (uv);
|
||||
em->SetAttribute ("ErrorRate", DoubleValue (0.01));
|
||||
|
||||
// The below hooks will cause drops and receptions to be counted
|
||||
output->SetAttribute ("ReceiveErrorModel", PointerValue (em));
|
||||
output->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&BurstErrorModelSimple::DropEvent, this));
|
||||
|
||||
// Send 10000 packets
|
||||
Simulator::Schedule (Seconds (0), &SendPacket, 10000, input, output->GetAddress ());
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
// With the burst error rate to be 0.01 and the burst size to be from 1 to 4,
|
||||
// we expect about 2.5 packets being dropped every 1000 packets.
|
||||
// That means for 10000 packets, we expect a total of about 250 packet drops.
|
||||
// For this specific RNG seed, we see 9772 receptions and 228 drops.
|
||||
NS_TEST_ASSERT_MSG_EQ (m_count, 9772, "Wrong number of receptions.");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_drops, 228 , "Wrong number of drops.");
|
||||
}
|
||||
|
||||
// This is the start of an error model test suite. For starters, this is
|
||||
// just testing that the SimpleNetDevice is working but this can be
|
||||
// extended to many more test cases in the future
|
||||
@@ -130,6 +234,7 @@ ErrorModelTestSuite::ErrorModelTestSuite ()
|
||||
: TestSuite ("error-model", UNIT)
|
||||
{
|
||||
AddTestCase (new ErrorModelSimple, TestCase::QUICK);
|
||||
AddTestCase (new BurstErrorModelSimple, TestCase::QUICK);
|
||||
}
|
||||
|
||||
// Do not forget to allocate an instance of this TestSuite
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* 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
|
||||
@@ -52,6 +53,13 @@
|
||||
* This code has been ported from ns-2 (queue/errmodel.{cc,h}
|
||||
*/
|
||||
|
||||
/* BurstErrorModel additions
|
||||
*
|
||||
* Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
|
||||
* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
|
||||
* James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "error-model.h"
|
||||
@@ -271,6 +279,135 @@ RateErrorModel::DoReset (void)
|
||||
/* re-initialize any state; no-op for now */
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// BurstErrorModel
|
||||
//
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (BurstErrorModel);
|
||||
|
||||
TypeId BurstErrorModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::BurstErrorModel")
|
||||
.SetParent<ErrorModel> ()
|
||||
.AddConstructor<BurstErrorModel> ()
|
||||
.AddAttribute ("ErrorRate", "The burst error event.",
|
||||
DoubleValue (0.0),
|
||||
MakeDoubleAccessor (&BurstErrorModel::m_burstRate),
|
||||
MakeDoubleChecker<double> ())
|
||||
.AddAttribute ("BurstStart", "The decision variable attached to this error model.",
|
||||
StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
|
||||
MakePointerAccessor (&BurstErrorModel::m_burstStart),
|
||||
MakePointerChecker<RandomVariableStream> ())
|
||||
.AddAttribute ("BurstSize", "The number of packets being corrupted at one drop.",
|
||||
StringValue ("ns3::UniformRandomVariable[Min=1|Max=4]"),
|
||||
MakePointerAccessor (&BurstErrorModel::m_burstSize),
|
||||
MakePointerChecker<RandomVariableStream> ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
BurstErrorModel::BurstErrorModel () : m_counter (0), m_currentBurstSz (0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BurstErrorModel::~BurstErrorModel ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
double
|
||||
BurstErrorModel::GetBurstRate (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_burstRate;
|
||||
}
|
||||
|
||||
void
|
||||
BurstErrorModel::SetBurstRate (double rate)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << rate);
|
||||
m_burstRate = rate;
|
||||
}
|
||||
|
||||
void
|
||||
BurstErrorModel::SetRandomVariable (Ptr<RandomVariableStream> ranVar)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ranVar);
|
||||
m_burstStart = ranVar;
|
||||
}
|
||||
|
||||
void
|
||||
BurstErrorModel::SetRandomBurstSize(Ptr<RandomVariableStream> burstSz)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << burstSz);
|
||||
m_burstSize = burstSz;
|
||||
}
|
||||
|
||||
int64_t
|
||||
BurstErrorModel::AssignStreams (int64_t stream)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << stream);
|
||||
m_burstStart->SetStream (stream);
|
||||
m_burstSize->SetStream(stream);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool
|
||||
BurstErrorModel::DoCorrupt (Ptr<Packet> p)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (!IsEnabled ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
double ranVar = m_burstStart ->GetValue();
|
||||
|
||||
if (ranVar < m_burstRate)
|
||||
{
|
||||
// get a new burst size for the new error event
|
||||
m_currentBurstSz = m_burstSize->GetInteger();
|
||||
NS_LOG_DEBUG ("new burst size selected: " << m_currentBurstSz);
|
||||
if (m_currentBurstSz == 0)
|
||||
{
|
||||
NS_LOG_WARN ("Burst size == 0; shouldn't happen");
|
||||
return false;
|
||||
}
|
||||
m_counter = 1; // start counting dropped packets
|
||||
return true; // drop this packet
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a burst error event
|
||||
if (m_counter < m_currentBurstSz)
|
||||
{
|
||||
// check to see if all the packets (determined by the last
|
||||
// generated m_currentBurstSz) have been dropped.
|
||||
// If not, drop 1 more packet
|
||||
m_counter++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// all packets in the last error event have been dropped
|
||||
// and there is no new error event, so do not drop the packet
|
||||
return false; // no error event
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BurstErrorModel::DoReset (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_counter = 0;
|
||||
m_currentBurstSz = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ListErrorModel
|
||||
//
|
||||
@@ -410,3 +547,4 @@ ReceiveListErrorModel::DoReset (void)
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* 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
|
||||
@@ -52,6 +53,13 @@
|
||||
* This code has been ported from ns-2 (queue/errmodel.{cc,h}
|
||||
*/
|
||||
|
||||
/* BurstErrorModel additions
|
||||
*
|
||||
* Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
|
||||
* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
|
||||
* James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
|
||||
*/
|
||||
|
||||
#ifndef ERROR_MODEL_H
|
||||
#define ERROR_MODEL_H
|
||||
|
||||
@@ -101,8 +109,8 @@ class Packet;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Two practical error models, a ListErrorModel and a RateErrorModel,
|
||||
* are currently implemented.
|
||||
* Four practical error models, a RateErrorModel, a BurstErrorModel,
|
||||
* a ListErrorModel, and a ReceiveListErrorModel, are currently implemented.
|
||||
*/
|
||||
class ErrorModel : public Object
|
||||
{
|
||||
@@ -223,6 +231,94 @@ private:
|
||||
Ptr<RandomVariableStream> m_ranvar;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Determine which bursts of packets are errored corresponding to
|
||||
* an underlying distribution, burst rate, and burst size.
|
||||
*
|
||||
* This object is used to flag packets as being lost/errored or not.
|
||||
* The two parameters that govern the behavior are the burst rate (or
|
||||
* equivalently, the mean duration/spacing between between error events),
|
||||
* and the burst size (or equivalently, the number of packets being flagged
|
||||
* as errored at each error event).
|
||||
*
|
||||
* Users can optionally provide RandomVariableStream objects;
|
||||
* the default for the decision variable is to use a Uniform(0,1) distribution;
|
||||
* the default for the burst size (number of packets) is to use a
|
||||
* discrete Uniform[1,4] distribution.
|
||||
*
|
||||
* For every packet, the model generates a random number based on the
|
||||
* decision variable, and compares it with the burst error rate to
|
||||
* determine if a burst error event should occur.
|
||||
* If a new error event occurs, the model to will generate a new burst size
|
||||
* to determine how many packets should be dropped in this particular burst
|
||||
* error event in addition to the current packet.
|
||||
*
|
||||
* When a second packet arrives, the model again determines if a new error
|
||||
* event should occur based on a newly generated decision variable and
|
||||
* the burst error rate. If a new error event is determined to occur,
|
||||
* the model will restart with a new burst size. Otherwise, the model will
|
||||
* resume the last error event and drop the packet provided that the
|
||||
* total number of packets that has been dropped does not exceed the
|
||||
* burst size.
|
||||
*
|
||||
* IsCorrupt() will not modify the packet data buffer
|
||||
*/
|
||||
class BurstErrorModel : public ErrorModel
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
BurstErrorModel ();
|
||||
virtual ~BurstErrorModel ();
|
||||
|
||||
/**
|
||||
* \returns the error rate being applied by the model
|
||||
*/
|
||||
double GetBurstRate (void) const;
|
||||
/**
|
||||
* \param burstRate the error rate to be used by the model
|
||||
*/
|
||||
void SetBurstRate (double rate);
|
||||
|
||||
/**
|
||||
* \param ranVariable A random variable distribution to generate random variates
|
||||
*/
|
||||
void SetRandomVariable (Ptr<RandomVariableStream>);
|
||||
|
||||
/**
|
||||
* \param burstSize A random variable distribution to generate random burst size
|
||||
*/
|
||||
void SetRandomBurstSize (Ptr<RandomVariableStream>);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned.
|
||||
*
|
||||
* \param stream first stream index to use
|
||||
* \return the number of stream indices assigned by this model
|
||||
*/
|
||||
int64_t AssignStreams (int64_t stream);
|
||||
|
||||
private:
|
||||
virtual bool DoCorrupt (Ptr<Packet> p);
|
||||
virtual void DoReset (void);
|
||||
|
||||
double m_burstRate; //the burst error event
|
||||
|
||||
Ptr<RandomVariableStream> m_burstStart; //the error decision variable
|
||||
|
||||
Ptr<RandomVariableStream> m_burstSize; //the number of packets being flagged as errored
|
||||
|
||||
uint32_t m_counter; //keep track of the number of packets being errored
|
||||
//until it reaches m_burstSize
|
||||
|
||||
uint32_t m_currentBurstSz; //the current burst size
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Provide a list of Packet uids to corrupt
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user