--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/error-model.cc Wed Nov 14 20:40:05 2007 -0800
@@ -0,0 +1,300 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ *
+ * 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: Tom Henderson <tomhend@u.washington.edu>
+ * This code has been ported from ns-2 (queue/errmodel.{cc,h}
+ */
+
+#include <math.h>
+
+#include "error-model.h"
+
+#include "ns3/packet.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/random-variable.h"
+#include "ns3/default-value.h"
+
+NS_LOG_COMPONENT_DEFINE ("ErrorModel");
+
+namespace ns3 {
+
+static ClassIdDefaultValue g_classIdErrorModelDefaultValue ("ErrorModel",
+ "Error Model", ErrorModel::iid, "RateErrorModel");
+
+const InterfaceId ErrorModel::iid =
+ MakeInterfaceId ("ErrorModel", Object::iid);
+
+ErrorModel::ErrorModel () :
+ m_enable (true)
+{
+ NS_LOG_FUNCTION;
+ SetInterfaceId (ErrorModel::iid);
+}
+
+ErrorModel::~ErrorModel ()
+{
+ NS_LOG_FUNCTION;
+}
+
+Ptr<ErrorModel>
+ErrorModel::CreateDefault (void)
+{
+ NS_LOG_FUNCTION;
+ ClassId classId = g_classIdErrorModelDefaultValue.GetValue ();
+ Ptr<ErrorModel> em = ComponentManager::Create<ErrorModel> (classId,
+ ErrorModel::iid);
+ return em;
+}
+
+bool
+ErrorModel::IsCorrupt (Packet& p)
+{
+ NS_LOG_FUNCTION;
+ bool result;
+ // Insert any pre-conditions here
+ result = DoCorrupt (p);
+ // Insert any post-conditions here
+ return result;
+}
+
+void
+ErrorModel::Reset (void)
+{
+ NS_LOG_FUNCTION;
+ DoReset ();
+}
+
+void
+ErrorModel::Enable (void)
+{
+ NS_LOG_FUNCTION;
+ m_enable = true;
+}
+
+void
+ErrorModel::Disable (void)
+{
+ NS_LOG_FUNCTION;
+ m_enable = false;
+}
+
+bool
+ErrorModel::IsEnabled (void) const
+{
+ NS_LOG_FUNCTION;
+ return m_enable;
+}
+
+//
+// RateErrorModel
+//
+
+const InterfaceId RateErrorModel::iid =
+ MakeInterfaceId ("RateErrorModel", ErrorModel::iid);
+
+const ClassId RateErrorModel::cid =
+ MakeClassId<RateErrorModel> ("RateErrorModel", ErrorModel::iid,
+ RateErrorModel::iid);
+
+// Defaults for rate/size
+static NumericDefaultValue<double> g_defaultRateErrorModelErrorRate
+ ("RateErrorModelErrorRate", "The error rate for the error model", 0.0);
+
+static EnumDefaultValue<enum ErrorUnit>
+ g_defaultRateErrorModelErrorUnit ("RateErrorModelErrorUnit",
+ "The error unit for this error model",
+ EU_BYTE, "EU_BYTE",
+ EU_PKT, "EU_PKT",
+ EU_BIT, "EU_BIT",
+ 0, (void*)0);
+
+RateErrorModel::RateErrorModel () :
+ m_unit (g_defaultRateErrorModelErrorUnit.GetValue() ),
+ m_rate (g_defaultRateErrorModelErrorRate.GetValue() )
+{
+ NS_LOG_FUNCTION;
+ // Assume a uniform random variable if user does not specify
+ m_ranvar = new UniformVariable ();
+ SetInterfaceId (RateErrorModel::iid);
+}
+
+RateErrorModel::~RateErrorModel ()
+{
+ NS_LOG_FUNCTION;
+ delete m_ranvar;
+}
+
+enum ErrorUnit
+RateErrorModel::GetUnit (void) const
+{
+ NS_LOG_FUNCTION;
+ return m_unit;
+}
+
+void
+RateErrorModel::SetUnit (enum ErrorUnit error_unit)
+{
+ NS_LOG_FUNCTION;
+ m_unit = error_unit;
+}
+
+double
+RateErrorModel::GetRate (void) const
+{
+ NS_LOG_FUNCTION;
+ return m_rate;
+}
+
+void
+RateErrorModel::SetRate (double rate)
+{
+ NS_LOG_FUNCTION;
+ m_rate = rate;
+}
+
+void
+RateErrorModel::SetRandomVariable (const RandomVariable &ranvar)
+{
+ NS_LOG_FUNCTION;
+ delete m_ranvar;
+ m_ranvar = ranvar.Copy ();
+}
+
+bool
+RateErrorModel::DoCorrupt (Packet& p)
+{
+ NS_LOG_FUNCTION;
+ if (!m_enable)
+ {
+ return false;
+ }
+ switch (m_unit)
+ {
+ case EU_PKT:
+ return DoCorruptPkt (p);
+ case EU_BYTE:
+ return DoCorruptByte (p);
+ case EU_BIT:
+ return DoCorruptBit (p);
+ default:
+ NS_ASSERT_MSG (false, "m_unit not supported yet");
+ break;
+ }
+ return false;
+}
+
+bool
+RateErrorModel::DoCorruptPkt (Packet& p)
+{
+ NS_LOG_FUNCTION;
+ return (m_ranvar->GetValue () < m_rate);
+}
+
+bool
+RateErrorModel::DoCorruptByte (Packet& p)
+{
+ NS_LOG_FUNCTION;
+ // compute pkt error rate, assume uniformly distributed byte error
+ double per = 1 - pow (1.0 - m_rate, p.GetSize ());
+ return (m_ranvar->GetValue () < per);
+}
+
+bool
+RateErrorModel::DoCorruptBit(Packet& p)
+{
+ NS_LOG_FUNCTION;
+ // compute pkt error rate, assume uniformly distributed bit error
+ double per = 1 - pow (1.0 - m_rate, (8 * p.GetSize ()) );
+ return (m_ranvar->GetValue () < per);
+}
+
+void
+RateErrorModel::DoReset (void)
+{
+ NS_LOG_FUNCTION;
+ /* re-initialize any state; no-op for now */
+}
+
+//
+// ListErrorModel
+//
+
+const InterfaceId ListErrorModel::iid =
+ MakeInterfaceId ("ListErrorModel", ErrorModel::iid);
+
+const ClassId ListErrorModel::cid =
+ MakeClassId<ListErrorModel> ("ListErrorModel", ErrorModel::iid,
+ ListErrorModel::iid);
+
+ListErrorModel::ListErrorModel ()
+{
+ NS_LOG_FUNCTION;
+ SetInterfaceId (ListErrorModel::iid);
+}
+
+ListErrorModel::~ListErrorModel ()
+{
+ NS_LOG_FUNCTION;
+}
+
+std::list<uint32_t>
+ListErrorModel::GetList (void) const
+{
+ NS_LOG_FUNCTION;
+ return m_packetList;
+}
+
+void
+ListErrorModel::SetList (const std::list<uint32_t> &packetlist)
+{
+ NS_LOG_FUNCTION;
+ m_packetList = packetlist;
+}
+
+// When performance becomes a concern, the list provided could be
+// converted to a dynamically-sized array of uint32_t to avoid
+// list iteration below.
+bool
+ListErrorModel::DoCorrupt (Packet& p)
+{
+ NS_LOG_FUNCTION;
+ if (!m_enable)
+ {
+ return false;
+ }
+ uint32_t uid = p.GetUid ();
+ for (PacketListCI i = m_packetList.begin ();
+ i != m_packetList.end (); i++)
+ {
+ if (uid == *i)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+ListErrorModel::DoReset (void)
+{
+ NS_LOG_FUNCTION;
+ m_packetList.clear();
+}
+
+
+} //namespace ns3