blob: 2a87ef6e8df80da5da93a924ca3cceaec11df8a1 [file] [log] [blame]
Alexander Afanasyev359bfb72012-01-09 18:42:50 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070021#include "ndn-consumer-window.h"
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080022#include "ns3/ptr.h"
23#include "ns3/log.h"
24#include "ns3/simulator.h"
25#include "ns3/packet.h"
26#include "ns3/callback.h"
27#include "ns3/string.h"
28#include "ns3/uinteger.h"
29#include "ns3/double.h"
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -070030#include "ns3/ndn-content-object.h"
31#include "ns3/ndn-interest.h"
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080032
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070033NS_LOG_COMPONENT_DEFINE ("ndn.ConsumerWindow");
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080034
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070035namespace ns3 {
36namespace ndn {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080037
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070038NS_OBJECT_ENSURE_REGISTERED (ConsumerWindow);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080039
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080040TypeId
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070041ConsumerWindow::GetTypeId (void)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080042{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070043 static TypeId tid = TypeId ("ns3::ndn::ConsumerWindow")
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070044 .SetGroupName ("Ndn")
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070045 .SetParent<Consumer> ()
46 .AddConstructor<ConsumerWindow> ()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080047
48 .AddAttribute ("Window", "Initial size of the window",
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -080049 StringValue ("1"),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070050 MakeUintegerAccessor (&ConsumerWindow::GetWindow, &ConsumerWindow::SetWindow),
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080051 MakeUintegerChecker<uint32_t> ())
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080052
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080053 .AddAttribute ("PayloadSize", "Average size of content object size (to calculate interest generation rate)",
54 UintegerValue (1040),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070055 MakeUintegerAccessor (&ConsumerWindow::GetPayloadSize, &ConsumerWindow::SetPayloadSize),
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080056 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070057
Alexander Afanasyevfdd45412013-05-16 22:24:33 -070058 .AddAttribute ("Size",
59 "Amount of data in megabytes to request, relying on PayloadSize parameter (alternative to MaxSeq attribute)",
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080060 DoubleValue (-1), // don't impose limit by default
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070061 MakeDoubleAccessor (&ConsumerWindow::GetMaxSize, &ConsumerWindow::SetMaxSize),
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080062 MakeDoubleChecker<double> ())
63
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070064 .AddAttribute ("MaxSeq",
Alexander Afanasyevfdd45412013-05-16 22:24:33 -070065 "Maximum sequence number to request (alternative to Size attribute, would activate only if Size is -1). "
66 "The parameter is activated only if Size negative (not set)",
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070067 IntegerValue (std::numeric_limits<uint32_t>::max ()),
Alexander Afanasyevfdd45412013-05-16 22:24:33 -070068 MakeUintegerAccessor (&ConsumerWindow::GetSeqMax, &ConsumerWindow::SetSeqMax),
69 MakeUintegerChecker<uint32_t> ())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070070
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080071 .AddAttribute ("InitialWindowOnTimeout", "Set window to initial value when timeout occurs",
72 BooleanValue (true),
73 MakeBooleanAccessor (&ConsumerWindow::m_setInitialWindowOnTimeout),
74 MakeBooleanChecker ())
75
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080076 .AddTraceSource ("WindowTrace",
77 "Window that controls how many outstanding interests are allowed",
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070078 MakeTraceSourceAccessor (&ConsumerWindow::m_window))
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -080079 .AddTraceSource ("InFlight",
80 "Current number of outstanding interests",
Alexander Afanasyevce8684f2013-05-03 11:12:14 -070081 MakeTraceSourceAccessor (&ConsumerWindow::m_inFlight))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080082 ;
83
84 return tid;
85}
86
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070087ConsumerWindow::ConsumerWindow ()
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080088 : m_payloadSize (1040)
89 , m_inFlight (0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080090{
91}
92
93void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070094ConsumerWindow::SetWindow (uint32_t window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080095{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080096 m_initialWindow = window;
97 m_window = m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080098}
99
100uint32_t
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700101ConsumerWindow::GetWindow () const
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800102{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800103 return m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800104}
105
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800106uint32_t
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700107ConsumerWindow::GetPayloadSize () const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800108{
109 return m_payloadSize;
110}
111
112void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700113ConsumerWindow::SetPayloadSize (uint32_t payload)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800114{
115 m_payloadSize = payload;
116}
117
118double
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700119ConsumerWindow::GetMaxSize () const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800120{
121 if (m_seqMax == 0)
122 return -1.0;
123
124 return m_maxSize;
125}
126
127void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700128ConsumerWindow::SetMaxSize (double size)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800129{
130 m_maxSize = size;
131 if (m_maxSize < 0)
132 {
133 m_seqMax = 0;
134 return;
135 }
136
137 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
138 NS_LOG_DEBUG ("MaxSeqNo: " << m_seqMax);
Alexander Afanasyev1180b042012-01-25 19:26:13 -0800139 // std::cout << "MaxSeqNo: " << m_seqMax << "\n";
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800140}
141
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700142uint32_t
143ConsumerWindow::GetSeqMax () const
144{
145 return m_seqMax;
146}
147
148void
149ConsumerWindow::SetSeqMax (uint32_t seqMax)
150{
151 if (m_maxSize < 0)
152 m_seqMax = seqMax;
153
154 // ignore otherwise
155}
156
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800157
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800158void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700159ConsumerWindow::ScheduleNextPacket ()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800160{
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800161 if (m_window == static_cast<uint32_t> (0))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800162 {
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800163 Simulator::Remove (m_sendEvent);
164
165 NS_LOG_DEBUG ("Next event in " << (std::min<double> (0.5, m_rtt->RetransmitTimeout ().ToDouble (Time::S))) << " sec");
166 m_sendEvent = Simulator::Schedule (Seconds (std::min<double> (0.5, m_rtt->RetransmitTimeout ().ToDouble (Time::S))),
167 &Consumer::SendPacket, this);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800168 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800169 else if (m_inFlight >= m_window)
170 {
171 // simply do nothing
172 }
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800173 else
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800174 {
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800175 if (m_sendEvent.IsRunning ())
176 {
177 Simulator::Remove (m_sendEvent);
178 }
179
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700180 m_sendEvent = Simulator::ScheduleNow (&Consumer::SendPacket, this);
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800181 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800182}
183
184///////////////////////////////////////////////////
185// Process incoming packets //
186///////////////////////////////////////////////////
187
188void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700189ConsumerWindow::OnData (Ptr<const Data> contentObject)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800190{
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700191 Consumer::OnData (contentObject);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800192
193 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800194
195 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800196 NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
197
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800198 ScheduleNextPacket ();
199}
200
201void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700202ConsumerWindow::OnNack (Ptr<const Interest> interest)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800203{
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700204 Consumer::OnNack (interest);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800205
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800206 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800207
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800208 if (m_window > static_cast<uint32_t> (0))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800209 {
210 // m_window = 0.5 * m_window;//m_window - 1;
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800211 m_window = std::max<uint32_t> (0, m_window - 1);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800212 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800213
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800214 NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
215
216 ScheduleNextPacket ();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800217}
218
219void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700220ConsumerWindow::OnTimeout (uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800221{
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800222 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800223
224 if (m_setInitialWindowOnTimeout)
225 {
226 // m_window = std::max<uint32_t> (0, m_window - 1);
227 m_window = m_initialWindow;
228 }
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800229
230 NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700231 Consumer::OnTimeout (sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800232}
233
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700234void
235ConsumerWindow::WillSendOutInterest (uint32_t sequenceNumber)
236{
237 m_inFlight ++;
238 Consumer::WillSendOutInterest (sequenceNumber);
239}
240
241
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700242} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800243} // namespace ns3