00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2007 University of Washington 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Tom Henderson <tomhend@u.washington.edu> 00019 * This code has been ported from ns-2 (queue/errmodel.{cc,h} 00020 */ 00021 #ifndef ERROR_MODEL_H 00022 #define ERROR_MODEL_H 00023 00024 #include <list> 00025 #include "ns3/object.h" 00026 #include "ns3/random-variable.h" 00027 00028 namespace ns3 { 00029 00030 class Packet; 00031 00032 /** 00033 * \ingroup common 00034 * \defgroup errormodel Error Model 00035 */ 00036 /** 00037 * \ingroup errormodel 00038 * \brief General error model that can be used to corrupt packets 00039 * 00040 * This object is used to flag packets as being lost/errored or not. 00041 * It is part of the Object framework and can be aggregated to 00042 * other ns3 objects and handled by the Ptr class. 00043 * 00044 * The main method is IsCorrupt(Ptr<Packet> p) which returns true if 00045 * the packet is to be corrupted according to the underlying model. 00046 * Depending on the error model, the packet itself may have its packet 00047 * data buffer errored or not, or side information may be returned to 00048 * the client in the form of a packet tag. 00049 * The object can have state (resettable by Reset()). 00050 * The object can also be enabled and disabled via two public member functions. 00051 * 00052 * Typical code (simplified) to use an ErrorModel may look something like 00053 * this: 00054 * \code 00055 * Ptr<ErrorModel> rem = CreateObject<RateErrorModel> (); 00056 * rem->SetRandomVariable (UniformVariable ()); 00057 * rem->SetRate (0.001); 00058 * ... 00059 * Ptr<Packet> p; 00060 * if (rem->IsCorrupt (p)) 00061 * { 00062 * dropTrace(p); 00063 * } else { 00064 * Forward (p); 00065 * } 00066 * \endcode 00067 * 00068 * Two practical error models, a ListErrorModel and a RateErrorModel, 00069 * are currently implemented. 00070 */ 00071 class ErrorModel : public Object 00072 { 00073 public: 00074 static TypeId GetTypeId (void); 00075 00076 ErrorModel (); 00077 virtual ~ErrorModel (); 00078 00079 /** 00080 * \returns true if the Packet is to be considered as errored/corrupted 00081 * \param pkt Packet to apply error model to 00082 */ 00083 bool IsCorrupt (Ptr<Packet> pkt); 00084 /** 00085 * Reset any state associated with the error model 00086 */ 00087 void Reset (void); 00088 /** 00089 * Enable the error model 00090 */ 00091 void Enable (void); 00092 /** 00093 * Disable the error model 00094 */ 00095 void Disable (void); 00096 /** 00097 * \return true if error model is enabled; false otherwise 00098 */ 00099 bool IsEnabled (void) const; 00100 00101 private: 00102 /* 00103 * These methods must be implemented by subclasses 00104 */ 00105 virtual bool DoCorrupt (Ptr<Packet>) = 0; 00106 virtual void DoReset (void) = 0; 00107 00108 bool m_enable; 00109 }; 00110 00111 enum ErrorUnit 00112 { 00113 EU_BIT, 00114 EU_BYTE, 00115 EU_PKT 00116 }; 00117 00118 /** 00119 * \brief Determine which packets are errored corresponding to an underlying 00120 * distribution, rate, and unit. 00121 * 00122 * This object is used to flag packets as being lost/errored or not. 00123 * The two parameters that govern the behavior are the rate (or 00124 * equivalently, the mean duration/spacing between errors), and the 00125 * unit (which may be per-bit, per-byte, and per-packet). 00126 * Users can optionally provide a RandomVariable object; the default 00127 * is to use a Uniform(0,1) distribution. 00128 00129 * Reset() on this model will do nothing 00130 * 00131 * IsCorrupt() will not modify the packet data buffer 00132 */ 00133 class RateErrorModel : public ErrorModel 00134 { 00135 public: 00136 static TypeId GetTypeId (void); 00137 00138 RateErrorModel (); 00139 virtual ~RateErrorModel (); 00140 00141 /** 00142 * \returns the ErrorUnit being used by the underlying model 00143 */ 00144 enum ErrorUnit GetUnit (void) const; 00145 /** 00146 * \param error_unit the ErrorUnit to be used by the underlying model 00147 */ 00148 void SetUnit (enum ErrorUnit error_unit); 00149 00150 /** 00151 * \returns the error rate being applied by the model 00152 */ 00153 double GetRate (void) const; 00154 /** 00155 * \param rate the error rate to be used by the model 00156 */ 00157 void SetRate (double rate); 00158 00159 /** 00160 * \param ranvar A random variable distribution to generate random variates 00161 */ 00162 void SetRandomVariable (const RandomVariable &ranvar); 00163 00164 private: 00165 virtual bool DoCorrupt (Ptr<Packet> p); 00166 virtual bool DoCorruptPkt (Ptr<Packet> p); 00167 virtual bool DoCorruptByte (Ptr<Packet> p); 00168 virtual bool DoCorruptBit (Ptr<Packet> p); 00169 virtual void DoReset (void); 00170 00171 enum ErrorUnit m_unit; 00172 double m_rate; 00173 00174 RandomVariable m_ranvar; 00175 }; 00176 00177 /** 00178 * \brief Provide a list of Packet uids to corrupt 00179 * 00180 * This object is used to flag packets as being lost/errored or not. 00181 * A note on performance: the list is assumed to be unordered, and 00182 * in general, Packet uids received may be unordered. Therefore, 00183 * each call to IsCorrupt() will result in a walk of the list with 00184 * the present underlying implementation. 00185 * 00186 * Note also that if one wants to target multiple packets from looking 00187 * at an (unerrored) trace file, the act of erroring a given packet may 00188 * cause subsequent packet uids to change. For instance, suppose one wants 00189 * to error packets 11 and 17 on a given device. It may be that erroring 00190 * packet 11 will cause the subsequent uid stream to change and 17 may no 00191 * longer correspond to the second packet that one wants to lose. Therefore, 00192 * be advised that it might take some trial and error to select the 00193 * right uids when multiple are provided. 00194 * 00195 * Reset() on this model will clear the list 00196 * 00197 * IsCorrupt() will not modify the packet data buffer 00198 */ 00199 class ListErrorModel : public ErrorModel 00200 { 00201 public: 00202 static TypeId GetTypeId (void); 00203 ListErrorModel (); 00204 virtual ~ListErrorModel (); 00205 00206 /** 00207 * \return a copy of the underlying list 00208 */ 00209 std::list<uint32_t> GetList (void) const; 00210 /** 00211 * \param packetlist The list of packet uids to error. 00212 * 00213 * This method overwrites any previously provided list. 00214 */ 00215 void SetList (const std::list<uint32_t> &packetlist); 00216 00217 private: 00218 virtual bool DoCorrupt (Ptr<Packet> p); 00219 virtual void DoReset (void); 00220 00221 typedef std::list<uint32_t> PacketList; 00222 typedef std::list<uint32_t>::const_iterator PacketListCI; 00223 00224 PacketList m_packetList; 00225 00226 }; 00227 00228 00229 } //namespace ns3 00230 #endif