--- a/examples/error-model/simple-error-model.cc Fri Apr 19 14:52:17 2013 -0400
+++ b/examples/error-model/simple-error-model.cc Fri Apr 19 12:58:25 2013 -0700
@@ -57,16 +57,21 @@
// 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 @@
// 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
--- a/src/network/doc/error-model.rst Fri Apr 19 14:52:17 2013 -0400
+++ b/src/network/doc/error-model.rst Fri Apr 19 12:58:25 2013 -0700
@@ -134,3 +134,20 @@
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.
--- a/src/network/test/error-model-test-suite.cc Fri Apr 19 14:52:17 2013 -0400
+++ b/src/network/test/error-model-test-suite.cc Fri Apr 19 12:58:25 2013 -0700
@@ -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 @@
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 @@
: TestSuite ("error-model", UNIT)
{
AddTestCase (new ErrorModelSimple, TestCase::QUICK);
+ AddTestCase (new BurstErrorModelSimple, TestCase::QUICK);
}
// Do not forget to allocate an instance of this TestSuite
--- a/src/network/utils/error-model.cc Fri Apr 19 14:52:17 2013 -0400
+++ b/src/network/utils/error-model.cc Fri Apr 19 12:58:25 2013 -0700
@@ -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 @@
/* 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 @@
} // namespace ns3
+
--- a/src/network/utils/error-model.h Fri Apr 19 14:52:17 2013 -0400
+++ b/src/network/utils/error-model.h Fri Apr 19 12:58:25 2013 -0700
@@ -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 @@
* }
* \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 @@
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
*