blob: 595842cd37be28b2de7cdcc749619c06949c10b0 [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 Afanasyev0c395372014-12-20 15:54:02 -080021#include "ndn-consumer-window.hpp"
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 Afanasyev0c395372014-12-20 15:54:02 -080030#include "ns3/ndn-data.hpp"
31#include "ns3/ndn-interest.hpp"
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080032
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080033NS_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 Afanasyevbe55cf62014-12-20 17:51:09 -080038NS_OBJECT_ENSURE_REGISTERED(ConsumerWindow);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080039
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080040TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080041ConsumerWindow::GetTypeId(void)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080042{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080043 static TypeId tid =
44 TypeId("ns3::ndn::ConsumerWindow")
45 .SetGroupName("Ndn")
46 .SetParent<Consumer>()
47 .AddConstructor<ConsumerWindow>()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080048
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080049 .AddAttribute("Window", "Initial size of the window", StringValue("1"),
50 MakeUintegerAccessor(&ConsumerWindow::GetWindow, &ConsumerWindow::SetWindow),
51 MakeUintegerChecker<uint32_t>())
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080052
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080053 .AddAttribute("PayloadSize",
54 "Average size of content object size (to calculate interest generation rate)",
55 UintegerValue(1040), MakeUintegerAccessor(&ConsumerWindow::GetPayloadSize,
56 &ConsumerWindow::SetPayloadSize),
57 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070058
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059 .AddAttribute("Size", "Amount of data in megabytes to request, relying on PayloadSize "
60 "parameter (alternative to MaxSeq attribute)",
61 DoubleValue(-1), // don't impose limit by default
62 MakeDoubleAccessor(&ConsumerWindow::GetMaxSize, &ConsumerWindow::SetMaxSize),
63 MakeDoubleChecker<double>())
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080064
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080065 .AddAttribute("MaxSeq", "Maximum sequence number to request (alternative to Size attribute, "
66 "would activate only if Size is -1). "
67 "The parameter is activated only if Size negative (not set)",
68 IntegerValue(std::numeric_limits<uint32_t>::max()),
69 MakeUintegerAccessor(&ConsumerWindow::GetSeqMax, &ConsumerWindow::SetSeqMax),
70 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070071
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072 .AddAttribute("InitialWindowOnTimeout", "Set window to initial value when timeout occurs",
73 BooleanValue(true),
74 MakeBooleanAccessor(&ConsumerWindow::m_setInitialWindowOnTimeout),
75 MakeBooleanChecker())
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080076
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080077 .AddTraceSource("WindowTrace",
78 "Window that controls how many outstanding interests are allowed",
79 MakeTraceSourceAccessor(&ConsumerWindow::m_window))
80 .AddTraceSource("InFlight", "Current number of outstanding interests",
81 MakeTraceSourceAccessor(&ConsumerWindow::m_inFlight));
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080082
83 return tid;
84}
85
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086ConsumerWindow::ConsumerWindow()
87 : m_payloadSize(1040)
88 , m_inFlight(0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080089{
90}
91
92void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080093ConsumerWindow::SetWindow(uint32_t window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080094{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080095 m_initialWindow = window;
96 m_window = m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080097}
98
99uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100ConsumerWindow::GetWindow() const
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800101{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800102 return m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800103}
104
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800105uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106ConsumerWindow::GetPayloadSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800107{
108 return m_payloadSize;
109}
110
111void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800112ConsumerWindow::SetPayloadSize(uint32_t payload)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800113{
114 m_payloadSize = payload;
115}
116
117double
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800118ConsumerWindow::GetMaxSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800119{
120 if (m_seqMax == 0)
121 return -1.0;
122
123 return m_maxSize;
124}
125
126void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127ConsumerWindow::SetMaxSize(double size)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800128{
129 m_maxSize = size;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130 if (m_maxSize < 0) {
131 m_seqMax = 0;
132 return;
133 }
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800134
135 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 NS_LOG_DEBUG("MaxSeqNo: " << m_seqMax);
Alexander Afanasyev1180b042012-01-25 19:26:13 -0800137 // std::cout << "MaxSeqNo: " << m_seqMax << "\n";
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800138}
139
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700140uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800141ConsumerWindow::GetSeqMax() const
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700142{
143 return m_seqMax;
144}
145
146void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800147ConsumerWindow::SetSeqMax(uint32_t seqMax)
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700148{
149 if (m_maxSize < 0)
150 m_seqMax = seqMax;
151
152 // ignore otherwise
153}
154
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800155void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156ConsumerWindow::ScheduleNextPacket()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800157{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 if (m_window == static_cast<uint32_t>(0)) {
159 Simulator::Remove(m_sendEvent);
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800160
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800161 NS_LOG_DEBUG(
162 "Next event in " << (std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S)))
163 << " sec");
164 m_sendEvent =
165 Simulator::Schedule(Seconds(
166 std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S))),
167 &Consumer::SendPacket, this);
168 }
169 else if (m_inFlight >= m_window) {
170 // simply do nothing
171 }
172 else {
173 if (m_sendEvent.IsRunning()) {
174 Simulator::Remove(m_sendEvent);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800175 }
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800176
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 m_sendEvent = Simulator::ScheduleNow(&Consumer::SendPacket, this);
178 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800179}
180
181///////////////////////////////////////////////////
182// Process incoming packets //
183///////////////////////////////////////////////////
184
185void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800186ConsumerWindow::OnData(Ptr<const Data> contentObject)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800187{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800188 Consumer::OnData(contentObject);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800189
190 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800191
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192 if (m_inFlight > static_cast<uint32_t>(0))
193 m_inFlight--;
194 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800195
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800196 ScheduleNextPacket();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800197}
198
199void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800200ConsumerWindow::OnNack(Ptr<const Interest> interest)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800201{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202 Consumer::OnNack(interest);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800203
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204 if (m_inFlight > static_cast<uint32_t>(0))
205 m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800206
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 if (m_window > static_cast<uint32_t>(0)) {
208 // m_window = 0.5 * m_window;//m_window - 1;
209 m_window = std::max<uint32_t>(0, m_window - 1);
210 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800211
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800212 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800213
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 ScheduleNextPacket();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800215}
216
217void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800218ConsumerWindow::OnTimeout(uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800219{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800220 if (m_inFlight > static_cast<uint32_t>(0))
221 m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800222
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800223 if (m_setInitialWindowOnTimeout) {
224 // m_window = std::max<uint32_t> (0, m_window - 1);
225 m_window = m_initialWindow;
226 }
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800227
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800228 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
229 Consumer::OnTimeout(sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800230}
231
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700232void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233ConsumerWindow::WillSendOutInterest(uint32_t sequenceNumber)
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700234{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800235 m_inFlight++;
236 Consumer::WillSendOutInterest(sequenceNumber);
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700237}
238
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700239} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800240} // namespace ns3