blob: c6c72182d99db0acc6e62996f6050f1b07b31043 [file] [log] [blame]
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2//
3// Copyright (c) 2006 Georgia Tech Research Corporation
4// (c) 2013 University of Arizona
5// (c) 2013 University of California, Los Angeles
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License version 2 as
9// published by the Free Software Foundation;
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program; if not, write to the Free Software
18// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19//
20// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
21// Cheng Yi <yic@email.arizona.edu>
22// Alexander Afanasyev <alexander.afanasyev@ucla.edu>
23//
24
25// Georgia Tech Network Simulator - Round Trip Time Estimation Class
26// George F. Riley. Georgia Tech, Spring 2002
27
Alexander Afanasyev0c395372014-12-20 15:54:02 -080028#include "ndn-rtt-mean-deviation.hpp"
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080029#include "ns3/simulator.h"
30#include "ns3/double.h"
31#include "ns3/integer.h"
32#include "ns3/uinteger.h"
33#include "ns3/log.h"
34
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080035NS_LOG_COMPONENT_DEFINE("ndn.RttMeanDeviation");
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080036
37namespace ns3 {
38namespace ndn {
39
40//---------------------------------------------------------------------------------
41// A modified version of Mean-Deviation Estimator optimized for NDN packet delivery
42
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080043NS_OBJECT_ENSURE_REGISTERED(RttMeanDeviation);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080044
45TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080046RttMeanDeviation::GetTypeId(void)
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080047{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080048 static TypeId tid =
49 TypeId("ns3::ndn::RttMeanDeviation")
50 .SetParent<RttEstimator>()
51 .AddConstructor<RttMeanDeviation>()
52 .AddAttribute("Gain", "Gain used in estimating the RTT (smoothed RTT), must be 0 < Gain < 1",
53 DoubleValue(0.125), MakeDoubleAccessor(&RttMeanDeviation::m_gain),
54 MakeDoubleChecker<double>())
55 .AddAttribute("Gain2", "Gain2 used in estimating the RTT (variance), must be 0 < Gain2 < 1",
56 DoubleValue(0.25), MakeDoubleAccessor(&RttMeanDeviation::m_gain2),
57 MakeDoubleChecker<double>());
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080058 return tid;
59}
60
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061RttMeanDeviation::RttMeanDeviation()
62 : m_variance(0)
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080063{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080064 NS_LOG_FUNCTION(this);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080065}
66
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080067RttMeanDeviation::RttMeanDeviation(const RttMeanDeviation& c)
68 : RttEstimator(c)
69 , m_gain(c.m_gain)
70 , m_gain2(c.m_gain2)
71 , m_variance(c.m_variance)
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080072{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073 NS_LOG_FUNCTION(this);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080074}
75
Yaogong Wang87cd0652013-05-28 11:00:45 -040076TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080077RttMeanDeviation::GetInstanceTypeId(void) const
Yaogong Wang87cd0652013-05-28 11:00:45 -040078{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080079 return GetTypeId();
Yaogong Wang87cd0652013-05-28 11:00:45 -040080}
81
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082void
83RttMeanDeviation::Measurement(Time m)
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -080084{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080085 NS_LOG_FUNCTION(this << m);
86 if (m_nSamples) { // Not first
87 Time err(m - m_currentEstimatedRtt);
88 double gErr = err.ToDouble(Time::S) * m_gain;
89 m_currentEstimatedRtt += Time::FromDouble(gErr, Time::S);
90 Time difference = Abs(err) - m_variance;
91 NS_LOG_DEBUG(
92 "m_variance += " << Time::FromDouble(difference.ToDouble(Time::S) * m_gain2, Time::S));
93 m_variance += Time::FromDouble(difference.ToDouble(Time::S) * m_gain2, Time::S);
94 }
95 else { // First sample
96 m_currentEstimatedRtt = m; // Set estimate to current
97 // variance = sample / 2; // And variance to current / 2
98 // m_variance = m; // try this why????
99 m_variance = Seconds(m.ToDouble(Time::S) / 2);
100 NS_LOG_DEBUG("(first sample) m_variance += " << m);
101 }
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800102 m_nSamples++;
103}
104
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105Time
106RttMeanDeviation::RetransmitTimeout()
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800107{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108 NS_LOG_FUNCTION(this);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800109
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110 double retval = std::min(m_maxRto.ToDouble(Time::S),
111 std::max(m_multiplier * m_minRto.ToDouble(Time::S),
112 m_multiplier * (m_currentEstimatedRtt.ToDouble(Time::S)
113 + 4 * m_variance.ToDouble(Time::S))));
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800114
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 NS_LOG_DEBUG("RetransmitTimeout: return " << retval);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800116
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800117 return Seconds(retval);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800118}
119
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800120Ptr<RttEstimator>
121RttMeanDeviation::Copy() const
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800122{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123 NS_LOG_FUNCTION(this);
124 return CopyObject<RttMeanDeviation>(this);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800125}
126
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127void
128RttMeanDeviation::Reset()
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800129{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130 NS_LOG_FUNCTION(this);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800131 // Reset to initial state
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132 m_variance = Seconds(0);
133 RttEstimator::Reset();
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800134}
135
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136void
137RttMeanDeviation::Gain(double g)
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800138{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139 NS_LOG_FUNCTION(this);
140 NS_ASSERT_MSG((g > 0) && (g < 1),
141 "RttMeanDeviation: Gain must be less than 1 and greater than 0");
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800142 m_gain = g;
143}
144
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145void
146RttMeanDeviation::SentSeq(SequenceNumber32 seq, uint32_t size)
147{
148 NS_LOG_FUNCTION(this << seq << size);
Cheng Yi3089c472013-03-07 18:12:41 -0700149
150 RttHistory_t::iterator i;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151 for (i = m_history.begin(); i != m_history.end(); ++i) {
152 if (seq == i->seq) { // Found it
153 i->retx = true;
154 break;
155 }
Cheng Yi3089c472013-03-07 18:12:41 -0700156 }
157
158 // Note that a particular sequence has been sent
159 if (i == m_history.end())
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 m_history.push_back(RttHistory(seq, size, Simulator::Now()));
Cheng Yi3089c472013-03-07 18:12:41 -0700161}
162
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800163Time
164RttMeanDeviation::AckSeq(SequenceNumber32 ackSeq)
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800165{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800166 NS_LOG_FUNCTION(this << ackSeq);
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800167 // An ack has been received, calculate rtt and log this measurement
168 // Note we use a linear search (O(n)) for this since for the common
169 // case the ack'ed packet will be at the head of the list
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800170 Time m = Seconds(0.0);
171 if (m_history.size() == 0)
172 return (m); // No pending history, just exit
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800173
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800174 for (RttHistory_t::iterator i = m_history.begin(); i != m_history.end(); ++i) {
175 if (ackSeq == i->seq) { // Found it
176 if (!i->retx) {
177 m = Simulator::Now() - i->time; // Elapsed time
178 Measurement(m); // Log the measurement
179 ResetMultiplier(); // Reset multiplier on valid measurement
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800180 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800181 m_history.erase(i);
182 break;
183 }
Alexander Afanasyevd9a7f192013-03-07 13:58:14 -0800184 }
185
186 return m;
187}
188
189} // namespace ndn
190} // namespace ns3