blob: b806190ffecc533e7973ca828804bc630be2858e [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",
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070076 MakeTraceSourceAccessor(&ConsumerWindow::m_window),
77 "ns3::ndn::ConsumerWindow::WindowTraceCallback")
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080078 .AddTraceSource("InFlight", "Current number of outstanding interests",
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070079 MakeTraceSourceAccessor(&ConsumerWindow::m_inFlight),
80 "ns3::ndn::ConsumerWindow::WindowTraceCallback");
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080081
82 return tid;
83}
84
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080085ConsumerWindow::ConsumerWindow()
86 : m_payloadSize(1040)
87 , m_inFlight(0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080088{
89}
90
91void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092ConsumerWindow::SetWindow(uint32_t window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080093{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080094 m_initialWindow = window;
95 m_window = m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080096}
97
98uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099ConsumerWindow::GetWindow() const
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800100{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800101 return m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800102}
103
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800104uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105ConsumerWindow::GetPayloadSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800106{
107 return m_payloadSize;
108}
109
110void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800111ConsumerWindow::SetPayloadSize(uint32_t payload)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800112{
113 m_payloadSize = payload;
114}
115
116double
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800117ConsumerWindow::GetMaxSize() const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800118{
119 if (m_seqMax == 0)
120 return -1.0;
121
122 return m_maxSize;
123}
124
125void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126ConsumerWindow::SetMaxSize(double size)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800127{
128 m_maxSize = size;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800129 if (m_maxSize < 0) {
130 m_seqMax = 0;
131 return;
132 }
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800133
134 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135 NS_LOG_DEBUG("MaxSeqNo: " << m_seqMax);
Alexander Afanasyev1180b042012-01-25 19:26:13 -0800136 // std::cout << "MaxSeqNo: " << m_seqMax << "\n";
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800137}
138
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700139uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140ConsumerWindow::GetSeqMax() const
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700141{
142 return m_seqMax;
143}
144
145void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146ConsumerWindow::SetSeqMax(uint32_t seqMax)
Alexander Afanasyevfdd45412013-05-16 22:24:33 -0700147{
148 if (m_maxSize < 0)
149 m_seqMax = seqMax;
150
151 // ignore otherwise
152}
153
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800154void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800155ConsumerWindow::ScheduleNextPacket()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800156{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800157 if (m_window == static_cast<uint32_t>(0)) {
158 Simulator::Remove(m_sendEvent);
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800159
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 NS_LOG_DEBUG(
161 "Next event in " << (std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S)))
162 << " sec");
163 m_sendEvent =
164 Simulator::Schedule(Seconds(
165 std::min<double>(0.5, m_rtt->RetransmitTimeout().ToDouble(Time::S))),
166 &Consumer::SendPacket, this);
167 }
168 else if (m_inFlight >= m_window) {
169 // simply do nothing
170 }
171 else {
172 if (m_sendEvent.IsRunning()) {
173 Simulator::Remove(m_sendEvent);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800174 }
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800175
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800176 m_sendEvent = Simulator::ScheduleNow(&Consumer::SendPacket, this);
177 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800178}
179
180///////////////////////////////////////////////////
181// Process incoming packets //
182///////////////////////////////////////////////////
183
184void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700185ConsumerWindow::OnData(shared_ptr<const Data> contentObject)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800186{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800187 Consumer::OnData(contentObject);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800188
189 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800190
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800191 if (m_inFlight > static_cast<uint32_t>(0))
192 m_inFlight--;
193 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800194
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800195 ScheduleNextPacket();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800196}
197
198void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800199ConsumerWindow::OnTimeout(uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800200{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 if (m_inFlight > static_cast<uint32_t>(0))
202 m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800203
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204 if (m_setInitialWindowOnTimeout) {
205 // m_window = std::max<uint32_t> (0, m_window - 1);
206 m_window = m_initialWindow;
207 }
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800208
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800209 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
210 Consumer::OnTimeout(sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800211}
212
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700213void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214ConsumerWindow::WillSendOutInterest(uint32_t sequenceNumber)
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700215{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800216 m_inFlight++;
217 Consumer::WillSendOutInterest(sequenceNumber);
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700218}
219
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700220} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800221} // namespace ns3