A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
error-model.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 University of Washington
4  * Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  *
20  * This file incorporates work covered by the following copyright and
21  * permission notice:
22  *
23  * Copyright (c) 1997 Regents of the University of California.
24  * All rights reserved.
25  *
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions
28  * are met:
29  * 1. Redistributions of source code must retain the above copyright
30  * notice, this list of conditions and the following disclaimer.
31  * 2. Redistributions in binary form must reproduce the above copyright
32  * notice, this list of conditions and the following disclaimer in the
33  * documentation and/or other materials provided with the distribution.
34  * 3. Neither the name of the University nor of the Laboratory may be used
35  * to endorse or promote products derived from this software without
36  * specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  *
50  * Contributed by the Daedalus Research Group, UC Berkeley
51  * (http://daedalus.cs.berkeley.edu)
52  *
53  * This code has been ported from ns-2 (queue/errmodel.{cc,h}
54  */
55 
56 /* BurstErrorModel additions
57  *
58  * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
59  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
60  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
61  */
62 
63 #include <cmath>
64 
65 #include "error-model.h"
66 
67 #include "ns3/packet.h"
68 #include "ns3/assert.h"
69 #include "ns3/log.h"
70 #include "ns3/boolean.h"
71 #include "ns3/enum.h"
72 #include "ns3/double.h"
73 #include "ns3/string.h"
74 #include "ns3/pointer.h"
75 
76 NS_LOG_COMPONENT_DEFINE ("ErrorModel");
77 
78 namespace ns3 {
79 
80 NS_OBJECT_ENSURE_REGISTERED (ErrorModel);
81 
82 TypeId ErrorModel::GetTypeId (void)
83 {
84  static TypeId tid = TypeId ("ns3::ErrorModel")
85  .SetParent<Object> ()
86  .AddAttribute ("IsEnabled", "Whether this ErrorModel is enabled or not.",
87  BooleanValue (true),
88  MakeBooleanAccessor (&ErrorModel::m_enable),
89  MakeBooleanChecker ())
90  ;
91  return tid;
92 }
93 
94 ErrorModel::ErrorModel () :
95  m_enable (true)
96 {
97  NS_LOG_FUNCTION (this);
98 }
99 
100 ErrorModel::~ErrorModel ()
101 {
102  NS_LOG_FUNCTION (this);
103 }
104 
105 bool
107 {
108  NS_LOG_FUNCTION (this << p);
109  bool result;
110  // Insert any pre-conditions here
111  result = DoCorrupt (p);
112  // Insert any post-conditions here
113  return result;
114 }
115 
116 void
118 {
119  NS_LOG_FUNCTION (this);
120  DoReset ();
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION (this);
127  m_enable = true;
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION (this);
134  m_enable = false;
135 }
136 
137 bool
139 {
140  NS_LOG_FUNCTION (this);
141  return m_enable;
142 }
143 
144 //
145 // RateErrorModel
146 //
147 
148 NS_OBJECT_ENSURE_REGISTERED (RateErrorModel);
149 
150 TypeId RateErrorModel::GetTypeId (void)
151 {
152  static TypeId tid = TypeId ("ns3::RateErrorModel")
153  .SetParent<ErrorModel> ()
154  .AddConstructor<RateErrorModel> ()
155  .AddAttribute ("ErrorUnit", "The error unit",
156  EnumValue (ERROR_UNIT_BYTE),
157  MakeEnumAccessor (&RateErrorModel::m_unit),
158  MakeEnumChecker (ERROR_UNIT_BIT, "ERROR_UNIT_BIT",
159  ERROR_UNIT_BYTE, "ERROR_UNIT_BYTE",
160  ERROR_UNIT_PACKET, "ERROR_UNIT_PACKET"))
161  .AddAttribute ("ErrorRate", "The error rate.",
162  DoubleValue (0.0),
163  MakeDoubleAccessor (&RateErrorModel::m_rate),
164  MakeDoubleChecker<double> ())
165  .AddAttribute ("RanVar", "The decision variable attached to this error model.",
166  StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
167  MakePointerAccessor (&RateErrorModel::m_ranvar),
168  MakePointerChecker<RandomVariableStream> ())
169  ;
170  return tid;
171 }
172 
173 
174 RateErrorModel::RateErrorModel ()
175 {
176  NS_LOG_FUNCTION (this);
177 }
178 
179 RateErrorModel::~RateErrorModel ()
180 {
181  NS_LOG_FUNCTION (this);
182 }
183 
184 RateErrorModel::ErrorUnit
186 {
187  NS_LOG_FUNCTION (this);
188  return m_unit;
189 }
190 
191 void
192 RateErrorModel::SetUnit (enum ErrorUnit error_unit)
193 {
194  NS_LOG_FUNCTION (this << error_unit);
195  m_unit = error_unit;
196 }
197 
198 double
200 {
201  NS_LOG_FUNCTION (this);
202  return m_rate;
203 }
204 
205 void
207 {
208  NS_LOG_FUNCTION (this << rate);
209  m_rate = rate;
210 }
211 
212 void
214 {
215  NS_LOG_FUNCTION (this << ranvar);
216  m_ranvar = ranvar;
217 }
218 
219 int64_t
221 {
222  NS_LOG_FUNCTION (this << stream);
223  m_ranvar->SetStream (stream);
224  return 1;
225 }
226 
227 bool
228 RateErrorModel::DoCorrupt (Ptr<Packet> p)
229 {
230  NS_LOG_FUNCTION (this << p);
231  if (!IsEnabled ())
232  {
233  return false;
234  }
235  switch (m_unit)
236  {
237  case ERROR_UNIT_PACKET:
238  return DoCorruptPkt (p);
239  case ERROR_UNIT_BYTE:
240  return DoCorruptByte (p);
241  case ERROR_UNIT_BIT:
242  return DoCorruptBit (p);
243  default:
244  NS_ASSERT_MSG (false, "m_unit not supported yet");
245  break;
246  }
247  return false;
248 }
249 
250 bool
251 RateErrorModel::DoCorruptPkt (Ptr<Packet> p)
252 {
253  NS_LOG_FUNCTION (this << p);
254  return (m_ranvar->GetValue () < m_rate);
255 }
256 
257 bool
258 RateErrorModel::DoCorruptByte (Ptr<Packet> p)
259 {
260  NS_LOG_FUNCTION (this << p);
261  // compute pkt error rate, assume uniformly distributed byte error
262  double per = 1 - std::pow (1.0 - m_rate, static_cast<double> (p->GetSize ()));
263  return (m_ranvar->GetValue () < per);
264 }
265 
266 bool
267 RateErrorModel::DoCorruptBit (Ptr<Packet> p)
268 {
269  NS_LOG_FUNCTION (this << p);
270  // compute pkt error rate, assume uniformly distributed bit error
271  double per = 1 - std::pow (1.0 - m_rate, static_cast<double> (8 * p->GetSize ()) );
272  return (m_ranvar->GetValue () < per);
273 }
274 
275 void
276 RateErrorModel::DoReset (void)
277 {
278  NS_LOG_FUNCTION (this);
279  /* re-initialize any state; no-op for now */
280 }
281 
282 
283 //
284 // BurstErrorModel
285 //
286 
287 NS_OBJECT_ENSURE_REGISTERED (BurstErrorModel);
288 
289 TypeId BurstErrorModel::GetTypeId (void)
290 {
291  static TypeId tid = TypeId ("ns3::BurstErrorModel")
292  .SetParent<ErrorModel> ()
293  .AddConstructor<BurstErrorModel> ()
294  .AddAttribute ("ErrorRate", "The burst error event.",
295  DoubleValue (0.0),
296  MakeDoubleAccessor (&BurstErrorModel::m_burstRate),
297  MakeDoubleChecker<double> ())
298  .AddAttribute ("BurstStart", "The decision variable attached to this error model.",
299  StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
300  MakePointerAccessor (&BurstErrorModel::m_burstStart),
301  MakePointerChecker<RandomVariableStream> ())
302  .AddAttribute ("BurstSize", "The number of packets being corrupted at one drop.",
303  StringValue ("ns3::UniformRandomVariable[Min=1|Max=4]"),
304  MakePointerAccessor (&BurstErrorModel::m_burstSize),
305  MakePointerChecker<RandomVariableStream> ())
306  ;
307  return tid;
308 }
309 
310 
311 BurstErrorModel::BurstErrorModel () : m_counter (0), m_currentBurstSz (0)
312 {
313 
314 }
315 
316 BurstErrorModel::~BurstErrorModel ()
317 {
318  NS_LOG_FUNCTION (this);
319 }
320 
321 double
323 {
324  NS_LOG_FUNCTION (this);
325  return m_burstRate;
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION (this << rate);
332  m_burstRate = rate;
333 }
334 
335 void
337 {
338  NS_LOG_FUNCTION (this << ranVar);
339  m_burstStart = ranVar;
340 }
341 
342 void
344 {
345  NS_LOG_FUNCTION (this << burstSz);
346  m_burstSize = burstSz;
347 }
348 
349 int64_t
351 {
352  NS_LOG_FUNCTION (this << stream);
353  m_burstStart->SetStream (stream);
354  m_burstSize->SetStream(stream);
355  return 2;
356 }
357 
358 bool
359 BurstErrorModel::DoCorrupt (Ptr<Packet> p)
360 {
361  NS_LOG_FUNCTION (this);
362  if (!IsEnabled ())
363  {
364  return false;
365  }
366  double ranVar = m_burstStart ->GetValue();
367 
368  if (ranVar < m_burstRate)
369  {
370  // get a new burst size for the new error event
371  m_currentBurstSz = m_burstSize->GetInteger();
372  NS_LOG_DEBUG ("new burst size selected: " << m_currentBurstSz);
373  if (m_currentBurstSz == 0)
374  {
375  NS_LOG_WARN ("Burst size == 0; shouldn't happen");
376  return false;
377  }
378  m_counter = 1; // start counting dropped packets
379  return true; // drop this packet
380  }
381  else
382  {
383  // not a burst error event
384  if (m_counter < m_currentBurstSz)
385  {
386  // check to see if all the packets (determined by the last
387  // generated m_currentBurstSz) have been dropped.
388  // If not, drop 1 more packet
389  m_counter++;
390  return true;
391  }
392  else
393  {
394  // all packets in the last error event have been dropped
395  // and there is no new error event, so do not drop the packet
396  return false; // no error event
397  }
398  }
399 }
400 
401 void
402 BurstErrorModel::DoReset (void)
403 {
404  NS_LOG_FUNCTION (this);
405  m_counter = 0;
406  m_currentBurstSz = 0;
407 
408 }
409 
410 
411 //
412 // ListErrorModel
413 //
414 
415 NS_OBJECT_ENSURE_REGISTERED (ListErrorModel);
416 
417 TypeId ListErrorModel::GetTypeId (void)
418 {
419  static TypeId tid = TypeId ("ns3::ListErrorModel")
420  .SetParent<ErrorModel> ()
421  .AddConstructor<ListErrorModel> ()
422  ;
423  return tid;
424 }
425 
426 ListErrorModel::ListErrorModel ()
427 {
428  NS_LOG_FUNCTION (this);
429 }
430 
431 ListErrorModel::~ListErrorModel ()
432 {
433  NS_LOG_FUNCTION (this);
434 }
435 
436 std::list<uint32_t>
438 {
439  NS_LOG_FUNCTION (this);
440  return m_packetList;
441 }
442 
443 void
444 ListErrorModel::SetList (const std::list<uint32_t> &packetlist)
445 {
446  NS_LOG_FUNCTION (this << &packetlist);
447  m_packetList = packetlist;
448 }
449 
450 // When performance becomes a concern, the list provided could be
451 // converted to a dynamically-sized array of uint32_t to avoid
452 // list iteration below.
453 bool
454 ListErrorModel::DoCorrupt (Ptr<Packet> p)
455 {
456  NS_LOG_FUNCTION (this << p);
457  if (!IsEnabled ())
458  {
459  return false;
460  }
461  uint32_t uid = p->GetUid ();
462  for (PacketListCI i = m_packetList.begin ();
463  i != m_packetList.end (); i++)
464  {
465  if (uid == *i)
466  {
467  return true;
468  }
469  }
470  return false;
471 }
472 
473 void
474 ListErrorModel::DoReset (void)
475 {
476  NS_LOG_FUNCTION (this);
477  m_packetList.clear ();
478 }
479 
480 //
481 // ReceiveListErrorModel
482 //
483 
484 NS_OBJECT_ENSURE_REGISTERED (ReceiveListErrorModel);
485 
486 TypeId ReceiveListErrorModel::GetTypeId (void)
487 {
488  static TypeId tid = TypeId ("ns3::ReceiveListErrorModel")
489  .SetParent<ErrorModel> ()
490  .AddConstructor<ReceiveListErrorModel> ()
491  ;
492  return tid;
493 }
494 
495 
496 ReceiveListErrorModel::ReceiveListErrorModel () :
497  m_timesInvoked (0)
498 {
499  NS_LOG_FUNCTION (this);
500 }
501 
502 ReceiveListErrorModel::~ReceiveListErrorModel ()
503 {
504  NS_LOG_FUNCTION (this);
505 }
506 
507 std::list<uint32_t>
509 {
510  NS_LOG_FUNCTION (this);
511  return m_packetList;
512 }
513 
514 void
515 ReceiveListErrorModel::SetList (const std::list<uint32_t> &packetlist)
516 {
517  NS_LOG_FUNCTION (this << &packetlist);
518  m_packetList = packetlist;
519 }
520 
521 bool
522 ReceiveListErrorModel::DoCorrupt (Ptr<Packet> p)
523 {
524  NS_LOG_FUNCTION (this << p);
525  if (!IsEnabled ())
526  {
527  return false;
528  }
529  m_timesInvoked += 1;
530  for (PacketListCI i = m_packetList.begin ();
531  i != m_packetList.end (); i++)
532  {
533  if (m_timesInvoked - 1 == *i)
534  {
535  return true;
536  }
537  }
538  return false;
539 }
540 
541 void
542 ReceiveListErrorModel::DoReset (void)
543 {
544  NS_LOG_FUNCTION (this);
545  m_packetList.clear ();
546 }
547 
548 
549 } // namespace ns3
550 
std::list< uint32_t > GetList(void) const
Definition: error-model.cc:437
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
hold variables of type string
Definition: string.h:19
std::list< uint32_t > GetList(void) const
Definition: error-model.cc:508
uint64_t GetUid(void) const
Definition: packet.cc:412
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
void SetRandomVariable(Ptr< RandomVariableStream >)
Definition: error-model.cc:336
General error model that can be used to corrupt packets.
Definition: error-model.h:115
virtual double GetValue(void)=0
Returns a random double from the underlying distribution.
void SetRandomBurstSize(Ptr< RandomVariableStream >)
Definition: error-model.cc:343
virtual uint32_t GetInteger(void)=0
Returns a random integer integer from the underlying distribution.
bool IsEnabled(void) const
Definition: error-model.cc:138
hold variables of type 'enum'
Definition: enum.h:37
int64_t AssignStreams(int64_t stream)
Definition: error-model.cc:350
void SetRate(double rate)
Definition: error-model.cc:206
void Disable(void)
Definition: error-model.cc:131
double GetRate(void) const
Definition: error-model.cc:199
void SetList(const std::list< uint32_t > &packetlist)
Definition: error-model.cc:515
void Reset(void)
Definition: error-model.cc:117
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void SetUnit(enum ErrorUnit error_unit)
Definition: error-model.cc:192
double GetBurstRate(void) const
Definition: error-model.cc:322
#define NS_LOG_WARN(msg)
Definition: log.h:246
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
bool IsCorrupt(Ptr< Packet > pkt)
Definition: error-model.cc:106
void SetList(const std::list< uint32_t > &packetlist)
Definition: error-model.cc:444
void SetRandomVariable(Ptr< RandomVariableStream >)
Definition: error-model.cc:213
int64_t AssignStreams(int64_t stream)
Definition: error-model.cc:220
Determine which packets are errored corresponding to an underlying distribution, rate, and unit.
Definition: error-model.h:173
Hold an floating point type.
Definition: double.h:41
RateErrorModel::ErrorUnit GetUnit(void) const
Definition: error-model.cc:185
a unique identifier for an interface.
Definition: type-id.h:44
void SetBurstRate(double rate)
Definition: error-model.cc:329
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void Enable(void)
Definition: error-model.cc:124