00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <iostream>
00029
00030 #include "rtt-estimator.h"
00031 #include "ns3/simulator.h"
00032 #include "ns3/double.h"
00033
00034 namespace ns3{
00035
00036 NS_OBJECT_ENSURE_REGISTERED (RttEstimator);
00037
00038
00039 TypeId
00040 RttEstimator::GetTypeId (void)
00041 {
00042 static TypeId tid = TypeId ("ns3::RttEstimator")
00043 .SetParent<Object> ()
00044 .AddAttribute ("MaxMultiplier",
00045 "XXX",
00046 DoubleValue (64.0),
00047 MakeDoubleAccessor (&RttEstimator::m_maxMultiplier),
00048 MakeDoubleChecker<double> ())
00049 .AddAttribute ("InitialEstimation",
00050 "XXX",
00051 TimeValue (Seconds (1.0)),
00052 MakeTimeAccessor (&RttEstimator::est),
00053 MakeTimeChecker ())
00054 .AddAttribute ("MinRTO",
00055 "Minimum retransmit timeout value",
00056 TimeValue (Seconds (0.2)),
00057 MakeTimeAccessor (&RttEstimator::minrto),
00058 MakeTimeChecker ())
00059 ;
00060 return tid;
00061 }
00062
00063
00064 RttHistory::RttHistory (SequenceNumber s, uint32_t c, Time t)
00065 : seq (s), count (c), time (t), retx (false)
00066 {
00067 }
00068
00069 RttHistory::RttHistory (const RttHistory& h)
00070 : seq (h.seq), count (h.count), time (h.time), retx (h.retx)
00071 {
00072 }
00073
00074
00075
00076 RttEstimator::RttEstimator () : next (1), history (),
00077 nSamples (0), multiplier (1.0)
00078 {
00079
00080 }
00081
00082 RttEstimator::RttEstimator(const RttEstimator& c)
00083 : Object (c), next(c.next), history(c.history),
00084 m_maxMultiplier (c.m_maxMultiplier), est(c.est), nSamples(c.nSamples),
00085 multiplier(c.multiplier)
00086 {}
00087
00088 RttEstimator::~RttEstimator ()
00089 {
00090 }
00091
00092 void RttEstimator::SentSeq (SequenceNumber s, uint32_t c)
00093 {
00094 if (s == next)
00095 {
00096 history.push_back (RttHistory (s, c, Simulator::Now () ));
00097 next = s + SequenceNumber (c);
00098 }
00099 else
00100 {
00101 for (RttHistory_t::iterator i = history.begin (); i != history.end (); ++i)
00102 {
00103 if ((s >= i->seq) && (s < (i->seq + SequenceNumber (i->count))))
00104 {
00105 i->retx = true;
00106
00107 if ((s + SequenceNumber (c)) > next)
00108 {
00109 next = s + SequenceNumber (c);
00110 i->count = ((s + SequenceNumber (c)) - i->seq);
00111 }
00112 break;
00113 }
00114 }
00115 }
00116 }
00117
00118 Time RttEstimator::AckSeq (SequenceNumber a)
00119 {
00120
00121
00122 Time m = Seconds (0.0);
00123 if (history.size () == 0) return (m);
00124 RttHistory& h = history.front ();
00125 if (!h.retx && a >= (h.seq + SequenceNumber (h.count)))
00126 {
00127 m = Simulator::Now () - h.time;
00128 Measurement(m);
00129 ResetMultiplier();
00130 }
00131
00132 while(history.size() > 0)
00133 {
00134 RttHistory& h = history.front ();
00135 if ((h.seq + SequenceNumber(h.count)) > a) break;
00136 history.pop_front ();
00137 }
00138 return m;
00139 }
00140
00141 void RttEstimator::ClearSent ()
00142 {
00143 next = 1;
00144 history.clear ();
00145 }
00146
00147 void RttEstimator::IncreaseMultiplier ()
00148 {
00149 double a;
00150 a = multiplier * 2.0;
00151 double b;
00152 b = m_maxMultiplier * 2.0;
00153 multiplier = std::min (multiplier * 2.0, m_maxMultiplier);
00154 }
00155
00156 void RttEstimator::ResetMultiplier ()
00157 {
00158 multiplier = 1.0;
00159 }
00160
00161 void RttEstimator::Reset ()
00162 {
00163 next = 1;
00164 est = Seconds (1.0);
00165 history.clear ();
00166 nSamples = 0;
00167 ResetMultiplier ();
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 NS_OBJECT_ENSURE_REGISTERED (RttMeanDeviation);
00177
00178 TypeId
00179 RttMeanDeviation::GetTypeId (void)
00180 {
00181 static TypeId tid = TypeId ("ns3::RttMeanDeviation")
00182 .SetParent<RttEstimator> ()
00183 .AddConstructor<RttMeanDeviation> ()
00184 .AddAttribute ("Gain",
00185 "XXX",
00186 DoubleValue (0.1),
00187 MakeDoubleAccessor (&RttMeanDeviation::gain),
00188 MakeDoubleChecker<double> ())
00189 ;
00190 return tid;
00191 }
00192
00193 RttMeanDeviation::RttMeanDeviation() :
00194 variance (ns3::Seconds(0))
00195 {
00196 }
00197
00198 RttMeanDeviation::RttMeanDeviation (const RttMeanDeviation& c)
00199 : RttEstimator (c), gain (c.gain), variance (c.variance)
00200 {
00201 }
00202
00203 void RttMeanDeviation::Measurement (Time m)
00204 {
00205 if (nSamples)
00206 {
00207 Time err = m - est;
00208 est = est + Scalar (gain) * err;
00209 err = Abs (err);
00210 variance = variance + Scalar (gain) * (err - variance);
00211 }
00212 else
00213 {
00214 est = m;
00215
00216 variance = m;
00217 }
00218 nSamples++;
00219 }
00220
00221 Time RttMeanDeviation::RetransmitTimeout ()
00222 {
00223
00224
00225 Time retval;
00226 if (variance < est / Scalar (4.0))
00227 {
00228 retval = est * Scalar (2 * multiplier);
00229 }
00230 else
00231 {
00232 retval = (est + Scalar (4) * variance) * Scalar (multiplier);
00233 }
00234 retval = Max (retval, minrto);
00235 return retval;
00236 }
00237
00238 Ptr<RttEstimator> RttMeanDeviation::Copy () const
00239 {
00240 return CopyObject<RttMeanDeviation> (this);
00241 }
00242
00243 void RttMeanDeviation::Reset ()
00244 {
00245 variance = Seconds (0.0);
00246 RttEstimator::Reset ();
00247 }
00248 }