A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
error-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 University of Washington
3 * Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 *
8 * This file incorporates work covered by the following copyright and
9 * permission notice:
10 *
11 * Copyright (c) 1997 Regents of the University of California.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor of the Laboratory may be used
23 * to endorse or promote products derived from this software without
24 * specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * Contributed by the Daedalus Research Group, UC Berkeley
39 * (http://daedalus.cs.berkeley.edu)
40 *
41 * This code has been ported from ns-2 (queue/errmodel.{cc,h}
42 */
43
44/* BurstErrorModel additions
45 *
46 * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
47 * ResiliNets Research Group https://resilinets.org/
48 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
49 */
50
51#include "error-model.h"
52
53#include "ns3/assert.h"
54#include "ns3/boolean.h"
55#include "ns3/double.h"
56#include "ns3/enum.h"
57#include "ns3/log.h"
58#include "ns3/packet.h"
59#include "ns3/pointer.h"
60#include "ns3/string.h"
61
62#include <cmath>
63
64namespace ns3
65{
66
67NS_LOG_COMPONENT_DEFINE("ErrorModel");
68
70
71TypeId
73{
74 static TypeId tid = TypeId("ns3::ErrorModel")
76 .SetGroupName("Network")
77 .AddAttribute("IsEnabled",
78 "Whether this ErrorModel is enabled or not.",
79 BooleanValue(true),
82 return tid;
83}
84
86 : m_enable(true)
87{
88 NS_LOG_FUNCTION(this);
89}
90
95
96bool
98{
99 NS_LOG_FUNCTION(this << p);
100 bool result;
101 // Insert any pre-conditions here
102 result = DoCorrupt(p);
103 // Insert any post-conditions here
104 return result;
105}
106
107void
109{
110 NS_LOG_FUNCTION(this);
111 DoReset();
112}
113
114void
116{
117 NS_LOG_FUNCTION(this);
118 m_enable = true;
119}
120
121void
123{
124 NS_LOG_FUNCTION(this);
125 m_enable = false;
126}
127
128bool
130{
131 NS_LOG_FUNCTION(this);
132 return m_enable;
133}
134
135//
136// RateErrorModel
137//
138
140
141TypeId
143{
144 static TypeId tid =
145 TypeId("ns3::RateErrorModel")
147 .SetGroupName("Network")
148 .AddConstructor<RateErrorModel>()
149 .AddAttribute("ErrorUnit",
150 "The error unit",
154 "ERROR_UNIT_BIT",
156 "ERROR_UNIT_BYTE",
158 "ERROR_UNIT_PACKET"))
159 .AddAttribute("ErrorRate",
160 "The error rate.",
161 DoubleValue(0.0),
164 .AddAttribute("RanVar",
165 "The decision variable attached to this error model.",
166 StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
169 return tid;
170}
171
176
181
184{
185 NS_LOG_FUNCTION(this);
186 return m_unit;
187}
188
189void
191{
192 NS_LOG_FUNCTION(this << error_unit);
193 m_unit = error_unit;
194}
195
196double
198{
199 NS_LOG_FUNCTION(this);
200 return m_rate;
201}
202
203void
205{
206 NS_LOG_FUNCTION(this << rate);
207 m_rate = rate;
208}
209
210void
212{
213 NS_LOG_FUNCTION(this << ranvar);
214 m_ranvar = ranvar;
215}
216
217int64_t
219{
220 NS_LOG_FUNCTION(this << stream);
221 m_ranvar->SetStream(stream);
222 return 1;
223}
224
225bool
227{
228 NS_LOG_FUNCTION(this << p);
229 if (!IsEnabled())
230 {
231 return false;
232 }
233 switch (m_unit)
234 {
236 return DoCorruptPkt(p);
237 case ERROR_UNIT_BYTE:
238 return DoCorruptByte(p);
239 case ERROR_UNIT_BIT:
240 return DoCorruptBit(p);
241 default:
242 NS_ASSERT_MSG(false, "m_unit not supported yet");
243 break;
244 }
245 return false;
246}
247
248bool
250{
251 NS_LOG_FUNCTION(this << p);
252 return (m_ranvar->GetValue() < m_rate);
253}
254
255bool
257{
258 NS_LOG_FUNCTION(this << p);
259 // compute pkt error rate, assume uniformly distributed byte error
260 double per = 1 - std::pow(1.0 - m_rate, static_cast<double>(p->GetSize()));
261 return (m_ranvar->GetValue() < per);
262}
263
264bool
266{
267 NS_LOG_FUNCTION(this << p);
268 // compute pkt error rate, assume uniformly distributed bit error
269 double per = 1 - std::pow(1.0 - m_rate, static_cast<double>(8 * p->GetSize()));
270 return (m_ranvar->GetValue() < per);
271}
272
273void
275{
276 NS_LOG_FUNCTION(this);
277 /* re-initialize any state; no-op for now */
278}
279
280//
281// BurstErrorModel
282//
283
285
286TypeId
288{
289 static TypeId tid =
290 TypeId("ns3::BurstErrorModel")
292 .SetGroupName("Network")
293 .AddConstructor<BurstErrorModel>()
294 .AddAttribute("ErrorRate",
295 "The burst error event.",
296 DoubleValue(0.0),
299 .AddAttribute("BurstStart",
300 "The decision variable attached to this error model.",
301 StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
304 .AddAttribute("BurstSize",
305 "The number of packets being corrupted at one drop.",
306 StringValue("ns3::UniformRandomVariable[Min=1|Max=4]"),
309 return tid;
310}
311
313 : m_counter(0),
314 m_currentBurstSz(0)
315{
316}
317
322
323double
325{
326 NS_LOG_FUNCTION(this);
327 return m_burstRate;
328}
329
330void
332{
333 NS_LOG_FUNCTION(this << rate);
334 m_burstRate = rate;
335}
336
337void
343
344void
346{
347 NS_LOG_FUNCTION(this << burstSz);
348 m_burstSize = burstSz;
349}
350
351int64_t
353{
354 NS_LOG_FUNCTION(this << stream);
355 m_burstStart->SetStream(stream);
356 m_burstSize->SetStream(stream);
357 return 2;
358}
359
360bool
362{
363 NS_LOG_FUNCTION(this);
364 if (!IsEnabled())
365 {
366 return false;
367 }
368 double ranVar = m_burstStart->GetValue();
369
370 if (ranVar < m_burstRate)
371 {
372 // get a new burst size for the new error event
374 NS_LOG_DEBUG("new burst size selected: " << m_currentBurstSz);
375 if (m_currentBurstSz == 0)
376 {
377 NS_LOG_WARN("Burst size == 0; shouldn't happen");
378 return false;
379 }
380 m_counter = 1; // start counting dropped packets
381 return true; // drop this packet
382 }
383 else
384 {
385 // not a burst error event
387 {
388 // check to see if all the packets (determined by the last
389 // generated m_currentBurstSz) have been dropped.
390 // If not, drop 1 more packet
391 m_counter++;
392 return true;
393 }
394 else
395 {
396 // all packets in the last error event have been dropped
397 // and there is no new error event, so do not drop the packet
398 return false; // no error event
399 }
400 }
401}
402
403void
410
411//
412// ListErrorModel
413//
414
416
417TypeId
419{
420 static TypeId tid = TypeId("ns3::ListErrorModel")
422 .SetGroupName("Network")
423 .AddConstructor<ListErrorModel>();
424 return tid;
425}
426
431
436
437std::list<uint64_t>
439{
440 NS_LOG_FUNCTION(this);
441 return m_packetList;
442}
443
444void
445ListErrorModel::SetList(const std::list<uint64_t>& packetlist)
446{
447 NS_LOG_FUNCTION(this << &packetlist);
448 m_packetList = packetlist;
449}
450
451// When performance becomes a concern, the list provided could be
452// converted to a dynamically-sized array of uint32_t to avoid
453// list iteration below.
454bool
456{
457 NS_LOG_FUNCTION(this << p);
458 if (!IsEnabled())
459 {
460 return false;
461 }
462 auto uid = p->GetUid();
463 for (auto i = m_packetList.begin(); i != m_packetList.end(); i++)
464 {
465 if (uid == *i)
466 {
467 return true;
468 }
469 }
470 return false;
471}
472
473void
475{
476 NS_LOG_FUNCTION(this);
477 m_packetList.clear();
478}
479
480//
481// ReceiveListErrorModel
482//
483
485
486TypeId
488{
489 static TypeId tid = TypeId("ns3::ReceiveListErrorModel")
491 .SetGroupName("Network")
492 .AddConstructor<ReceiveListErrorModel>();
493 return tid;
494}
495
497 : m_timesInvoked(0)
498{
499 NS_LOG_FUNCTION(this);
500}
501
506
507std::list<uint32_t>
509{
510 NS_LOG_FUNCTION(this);
511 return m_packetList;
512}
513
514void
515ReceiveListErrorModel::SetList(const std::list<uint32_t>& packetlist)
516{
517 NS_LOG_FUNCTION(this << &packetlist);
518 m_packetList = packetlist;
519}
520
521bool
523{
524 NS_LOG_FUNCTION(this << p);
525 if (!IsEnabled())
526 {
527 return false;
528 }
529 m_timesInvoked += 1;
530 for (auto i = m_packetList.begin(); i != m_packetList.end(); i++)
531 {
532 if (m_timesInvoked - 1 == *i)
533 {
534 return true;
535 }
536 }
537 return false;
538}
539
540void
546
548
549TypeId
551{
552 static TypeId tid =
553 TypeId("ns3::BinaryErrorModel").SetParent<ErrorModel>().AddConstructor<BinaryErrorModel>();
554 return tid;
555}
556
562
567
568bool
570{
571 NS_LOG_FUNCTION(this);
572 if (!IsEnabled())
573 {
574 return false;
575 }
576 bool ret = m_counter % 2;
577 m_counter++;
578 return ret;
579}
580
581void
587
588} // namespace ns3
The simplest error model, corrupts even packets and does not corrupt odd ones.
uint8_t m_counter
internal state counter.
void DoReset() override
Re-initialize any state.
~BinaryErrorModel() override
static TypeId GetTypeId()
Get the type ID.
bool DoCorrupt(Ptr< Packet > p) override
Corrupt a packet according to the specified model.
Determine which bursts of packets are errored corresponding to an underlying distribution,...
Ptr< RandomVariableStream > m_burstStart
the error decision variable
void SetRandomVariable(Ptr< RandomVariableStream > ranVar)
bool DoCorrupt(Ptr< Packet > p) override
Corrupt a packet according to the specified model.
Ptr< RandomVariableStream > m_burstSize
the number of packets being flagged as errored
uint32_t m_currentBurstSz
the current burst size
double GetBurstRate() const
void DoReset() override
Re-initialize any state.
static TypeId GetTypeId()
Get the type ID.
double m_burstRate
the burst error event
void SetBurstRate(double rate)
uint32_t m_counter
keep track of the number of packets being errored until it reaches m_burstSize
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
~BurstErrorModel() override
void SetRandomBurstSize(Ptr< RandomVariableStream > burstSz)
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
General error model that can be used to corrupt packets.
bool m_enable
True if the error model is enabled.
void Reset()
Reset any state associated with the error model.
void Enable()
Enable the error model.
bool IsEnabled() const
~ErrorModel() override
virtual bool DoCorrupt(Ptr< Packet > p)=0
Corrupt a packet according to the specified model.
virtual void DoReset()=0
Re-initialize any state.
static TypeId GetTypeId()
Get the type ID.
void Disable()
Disable the error model.
bool IsCorrupt(Ptr< Packet > pkt)
Note: Depending on the error model, this function may or may not alter the contents of the packet upo...
Provide a list of Packet uids to corrupt.
bool DoCorrupt(Ptr< Packet > p) override
Corrupt a packet according to the specified model.
~ListErrorModel() override
void DoReset() override
Re-initialize any state.
void SetList(const std::list< uint64_t > &packetlist)
std::list< uint64_t > GetList() const
static TypeId GetTypeId()
Get the type ID.
PacketList m_packetList
container of Uid of packets to corrupt
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
virtual double GetValue()=0
Get the next random value drawn from the distribution.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Determine which packets are errored corresponding to an underlying distribution, rate,...
double m_rate
Error rate.
virtual bool DoCorruptByte(Ptr< Packet > p)
Corrupt a packet (Byte unit).
ErrorUnit m_unit
Error rate unit.
void SetRate(double rate)
void DoReset() override
Re-initialize any state.
virtual bool DoCorruptBit(Ptr< Packet > p)
Corrupt a packet (bit unit).
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void SetUnit(ErrorUnit error_unit)
static TypeId GetTypeId()
Get the type ID.
~RateErrorModel() override
bool DoCorrupt(Ptr< Packet > p) override
Corrupt a packet according to the specified model.
Ptr< RandomVariableStream > m_ranvar
rng stream
virtual bool DoCorruptPkt(Ptr< Packet > p)
Corrupt a packet (packet unit).
void SetRandomVariable(Ptr< RandomVariableStream >)
RateErrorModel::ErrorUnit GetUnit() const
double GetRate() const
Provide a list of Packets to corrupt.
void DoReset() override
Re-initialize any state.
bool DoCorrupt(Ptr< Packet > p) override
Corrupt a packet according to the specified model.
static TypeId GetTypeId()
Get the type ID.
uint32_t m_timesInvoked
number of times the error model has been invoked
std::list< uint32_t > GetList() const
PacketList m_packetList
container of sequence number of packets to corrupt
void SetList(const std::list< uint32_t > &packetlist)
Hold variables of type string.
Definition string.h:45
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition enum.h:221