blob: d1531bd3a0dff2fb87f86af89b81dac20f33ce5b [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"
30
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080031NS_LOG_COMPONENT_DEFINE("ndn.ConsumerWindow");
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080032
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070033namespace ns3 {
34namespace ndn {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080035
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080036NS_OBJECT_ENSURE_REGISTERED(ConsumerWindow);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080037
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080038TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080039ConsumerWindow::GetTypeId(void)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080040{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080041 static TypeId tid =
42 TypeId("ns3::ndn::ConsumerWindow")
43 .SetGroupName("Ndn")
44 .SetParent<Consumer>()
45 .AddConstructor<ConsumerWindow>()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080046
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080047 .AddAttribute("Window", "Initial size of the window", StringValue("1"),
48 MakeUintegerAccessor(&ConsumerWindow::GetWindow, &ConsumerWindow::SetWindow),
49 MakeUintegerChecker<uint32_t>())
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080050
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080051 .AddAttribute("PayloadSize",
52 "Average size of content object size (to calculate interest generation rate)",
53 UintegerValue(1040), MakeUintegerAccessor(&ConsumerWindow::GetPayloadSize,
54 &ConsumerWindow::SetPayloadSize),
55 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070056
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 .AddAttribute("Size", "Amount of data in megabytes to request, relying on PayloadSize "
58 "parameter (alternative to MaxSeq attribute)",
59 DoubleValue(-1), // don't impose limit by default
60 MakeDoubleAccessor(&ConsumerWindow::GetMaxSize, &ConsumerWindow::SetMaxSize),
61 MakeDoubleChecker<double>())
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080062
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063 .AddAttribute("MaxSeq", "Maximum sequence number to request (alternative to Size attribute, "
64 "would activate only if Size is -1). "
65 "The parameter is activated only if Size negative (not set)",
66 IntegerValue(std::numeric_limits<uint32_t>::max()),
67 MakeUintegerAccessor(&ConsumerWindow::GetSeqMax, &ConsumerWindow::SetSeqMax),
68 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070069
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070 .AddAttribute("InitialWindowOnTimeout", "Set window to initial value when timeout occurs",
71 BooleanValue(true),
72 MakeBooleanAccessor(&ConsumerWindow::m_setInitialWindowOnTimeout),
73 MakeBooleanChecker())
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080074
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080075 .AddTraceSource("WindowTrace",
76 "Window that controls how many outstanding interests are allowed",
77 MakeTraceSourceAccessor(&ConsumerWindow::m_window))
78 .AddTraceSource("InFlight", "Current number of outstanding interests",
79 MakeTraceSourceAccessor(&ConsumerWindow::m_inFlight));
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080080
81 return tid;
82}
83
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080084ConsumerWindow::ConsumerWindow()
85 : m_payloadSize(1040)
86 , m_inFlight(0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080087{
88}
89
90void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080091ConsumerWindow::SetWindow(uint32_t window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080092{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080093 m_initialWindow = window;
94 m_window = m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080095}
96
97uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098ConsumerWindow::GetWindow() const
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080099{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800100 return m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800101}
102
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800103uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104ConsumerWindow::GetPayloadSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800105{
106 return m_payloadSize;
107}
108
109void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110ConsumerWindow::SetPayloadSize(uint32_t payload)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800111{
112 m_payloadSize = payload;
113}
114
115double
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800116ConsumerWindow::GetMaxSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800117{
118 if (m_seqMax == 0)
119 return -1.0;
120
121 return m_maxSize;
122}
123
124void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125ConsumerWindow::SetMaxSize(double size)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800126{
127 m_maxSize = size;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128 if (m_maxSize < 0) {
129 m_seqMax = 0;
130 return;
131 }
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800132
133 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134 NS_LOG_DEBUG("MaxSeqNo: " << m_seqMax);
Alexander Afanasyev1180b042012-01-25 19:26:13 -0800135 // std::cout << "MaxSeqNo: " << m_seqMax << "\n";
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800136}
137
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700138uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139ConsumerWindow::GetSeqMax() const
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700140{
141 return m_seqMax;
142}
143
144void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145ConsumerWindow::SetSeqMax(uint32_t seqMax)
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700146{
147 if (m_maxSize < 0)
148 m_seqMax = seqMax;
149
150 // ignore otherwise
151}
152
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800153void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800154ConsumerWindow::ScheduleNextPacket()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800155{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156 if (m_window == static_cast<uint32_t>(0)) {
157 Simulator::Remove(m_sendEvent);
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800158
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800159 NS_LOG_DEBUG(
160 "Next event in " << (std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S)))
161 << " sec");
162 m_sendEvent =
163 Simulator::Schedule(Seconds(
164 std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S))),
165 &Consumer::SendPacket, this);
166 }
167 else if (m_inFlight >= m_window) {
168 // simply do nothing
169 }
170 else {
171 if (m_sendEvent.IsRunning()) {
172 Simulator::Remove(m_sendEvent);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800173 }
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800174
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800175 m_sendEvent = Simulator::ScheduleNow(&Consumer::SendPacket, this);
176 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800177}
178
179///////////////////////////////////////////////////
180// Process incoming packets //
181///////////////////////////////////////////////////
182
183void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700184ConsumerWindow::OnData(shared_ptr<const Data> contentObject)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800185{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800186 Consumer::OnData(contentObject);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800187
188 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800189
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190 if (m_inFlight > static_cast<uint32_t>(0))
191 m_inFlight--;
192 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800193
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800194 ScheduleNextPacket();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800195}
196
197void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700198ConsumerWindow::OnNack(shared_ptr<const Interest> interest)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800199{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800200 Consumer::OnNack(interest);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800201
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202 if (m_inFlight > static_cast<uint32_t>(0))
203 m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800204
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800205 if (m_window > static_cast<uint32_t>(0)) {
206 // m_window = 0.5 * m_window;//m_window - 1;
207 m_window = std::max<uint32_t>(0, m_window - 1);
208 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800209
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800210 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800211
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800212 ScheduleNextPacket();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800213}
214
215void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800216ConsumerWindow::OnTimeout(uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800217{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800218 if (m_inFlight > static_cast<uint32_t>(0))
219 m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800220
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 if (m_setInitialWindowOnTimeout) {
222 // m_window = std::max<uint32_t> (0, m_window - 1);
223 m_window = m_initialWindow;
224 }
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800225
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800226 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
227 Consumer::OnTimeout(sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800228}
229
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700230void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800231ConsumerWindow::WillSendOutInterest(uint32_t sequenceNumber)
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700232{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233 m_inFlight++;
234 Consumer::WillSendOutInterest(sequenceNumber);
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700235}
236
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700237} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800238} // namespace ns3