blob: d02ea1db85a777015ce9b99a3a46bf9227750aa3 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev359bfb72012-01-09 18:42:50 -08004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev359bfb72012-01-09 18:42:50 -08007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080019
Alexander Afanasyev0c395372014-12-20 15:54:02 -080020#include "ndn-consumer-window.hpp"
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080021#include "ns3/ptr.h"
22#include "ns3/log.h"
23#include "ns3/simulator.h"
24#include "ns3/packet.h"
25#include "ns3/callback.h"
26#include "ns3/string.h"
27#include "ns3/uinteger.h"
28#include "ns3/double.h"
29
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080030NS_LOG_COMPONENT_DEFINE("ndn.ConsumerWindow");
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080031
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070032namespace ns3 {
33namespace ndn {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080034
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080035NS_OBJECT_ENSURE_REGISTERED(ConsumerWindow);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080036
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080037TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080038ConsumerWindow::GetTypeId(void)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080039{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080040 static TypeId tid =
41 TypeId("ns3::ndn::ConsumerWindow")
42 .SetGroupName("Ndn")
43 .SetParent<Consumer>()
44 .AddConstructor<ConsumerWindow>()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080045
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080046 .AddAttribute("Window", "Initial size of the window", StringValue("1"),
47 MakeUintegerAccessor(&ConsumerWindow::GetWindow, &ConsumerWindow::SetWindow),
48 MakeUintegerChecker<uint32_t>())
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080049
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050 .AddAttribute("PayloadSize",
51 "Average size of content object size (to calculate interest generation rate)",
52 UintegerValue(1040), MakeUintegerAccessor(&ConsumerWindow::GetPayloadSize,
53 &ConsumerWindow::SetPayloadSize),
54 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070055
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080056 .AddAttribute("Size", "Amount of data in megabytes to request, relying on PayloadSize "
57 "parameter (alternative to MaxSeq attribute)",
58 DoubleValue(-1), // don't impose limit by default
59 MakeDoubleAccessor(&ConsumerWindow::GetMaxSize, &ConsumerWindow::SetMaxSize),
60 MakeDoubleChecker<double>())
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080061
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080062 .AddAttribute("MaxSeq", "Maximum sequence number to request (alternative to Size attribute, "
63 "would activate only if Size is -1). "
64 "The parameter is activated only if Size negative (not set)",
65 IntegerValue(std::numeric_limits<uint32_t>::max()),
66 MakeUintegerAccessor(&ConsumerWindow::GetSeqMax, &ConsumerWindow::SetSeqMax),
67 MakeUintegerChecker<uint32_t>())
Alexander Afanasyevee4ce7e2013-05-07 11:30:21 -070068
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080069 .AddAttribute("InitialWindowOnTimeout", "Set window to initial value when timeout occurs",
70 BooleanValue(true),
71 MakeBooleanAccessor(&ConsumerWindow::m_setInitialWindowOnTimeout),
72 MakeBooleanChecker())
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080073
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 .AddTraceSource("WindowTrace",
75 "Window that controls how many outstanding interests are allowed",
76 MakeTraceSourceAccessor(&ConsumerWindow::m_window))
77 .AddTraceSource("InFlight", "Current number of outstanding interests",
78 MakeTraceSourceAccessor(&ConsumerWindow::m_inFlight));
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080079
80 return tid;
81}
82
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080083ConsumerWindow::ConsumerWindow()
84 : m_payloadSize(1040)
85 , m_inFlight(0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080086{
87}
88
89void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090ConsumerWindow::SetWindow(uint32_t window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080091{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080092 m_initialWindow = window;
93 m_window = m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080094}
95
96uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080097ConsumerWindow::GetWindow() const
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080098{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080099 return m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800100}
101
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800102uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800103ConsumerWindow::GetPayloadSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800104{
105 return m_payloadSize;
106}
107
108void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800109ConsumerWindow::SetPayloadSize(uint32_t payload)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800110{
111 m_payloadSize = payload;
112}
113
114double
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115ConsumerWindow::GetMaxSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800116{
117 if (m_seqMax == 0)
118 return -1.0;
119
120 return m_maxSize;
121}
122
123void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124ConsumerWindow::SetMaxSize(double size)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800125{
126 m_maxSize = size;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127 if (m_maxSize < 0) {
128 m_seqMax = 0;
129 return;
130 }
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800131
132 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 NS_LOG_DEBUG("MaxSeqNo: " << m_seqMax);
Alexander Afanasyev1180b042012-01-25 19:26:13 -0800134 // std::cout << "MaxSeqNo: " << m_seqMax << "\n";
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800135}
136
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700137uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800138ConsumerWindow::GetSeqMax() const
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700139{
140 return m_seqMax;
141}
142
143void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144ConsumerWindow::SetSeqMax(uint32_t seqMax)
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700145{
146 if (m_maxSize < 0)
147 m_seqMax = seqMax;
148
149 // ignore otherwise
150}
151
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800152void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800153ConsumerWindow::ScheduleNextPacket()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800154{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800155 if (m_window == static_cast<uint32_t>(0)) {
156 Simulator::Remove(m_sendEvent);
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800157
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 NS_LOG_DEBUG(
159 "Next event in " << (std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S)))
160 << " sec");
161 m_sendEvent =
162 Simulator::Schedule(Seconds(
163 std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S))),
164 &Consumer::SendPacket, this);
165 }
166 else if (m_inFlight >= m_window) {
167 // simply do nothing
168 }
169 else {
170 if (m_sendEvent.IsRunning()) {
171 Simulator::Remove(m_sendEvent);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800172 }
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800173
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800174 m_sendEvent = Simulator::ScheduleNow(&Consumer::SendPacket, this);
175 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800176}
177
178///////////////////////////////////////////////////
179// Process incoming packets //
180///////////////////////////////////////////////////
181
182void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700183ConsumerWindow::OnData(shared_ptr<const Data> contentObject)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800184{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800185 Consumer::OnData(contentObject);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800186
187 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800188
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800189 if (m_inFlight > static_cast<uint32_t>(0))
190 m_inFlight--;
191 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800192
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800193 ScheduleNextPacket();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800194}
195
196void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197ConsumerWindow::OnTimeout(uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800198{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800199 if (m_inFlight > static_cast<uint32_t>(0))
200 m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800201
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202 if (m_setInitialWindowOnTimeout) {
203 // m_window = std::max<uint32_t> (0, m_window - 1);
204 m_window = m_initialWindow;
205 }
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800206
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
208 Consumer::OnTimeout(sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800209}
210
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700211void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800212ConsumerWindow::WillSendOutInterest(uint32_t sequenceNumber)
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700213{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 m_inFlight++;
215 Consumer::WillSendOutInterest(sequenceNumber);
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700216}
217
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700218} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800219} // namespace ns3