blob: 79c31e2a52a7e294815d718c610374fc740d3ade [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"
Xinyu Ma60562d42019-03-14 14:05:20 -070029#include <limits>
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080030
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",
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070077 MakeTraceSourceAccessor(&ConsumerWindow::m_window),
78 "ns3::ndn::ConsumerWindow::WindowTraceCallback")
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080079 .AddTraceSource("InFlight", "Current number of outstanding interests",
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070080 MakeTraceSourceAccessor(&ConsumerWindow::m_inFlight),
81 "ns3::ndn::ConsumerWindow::WindowTraceCallback");
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) {
Xinyu Ma60562d42019-03-14 14:05:20 -0700131 m_seqMax = std::numeric_limits<uint32_t>::max();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132 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
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700186ConsumerWindow::OnData(shared_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::OnTimeout(uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800201{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202 if (m_inFlight > static_cast<uint32_t>(0))
203 m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800204
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800205 if (m_setInitialWindowOnTimeout) {
206 // m_window = std::max<uint32_t> (0, m_window - 1);
207 m_window = m_initialWindow;
208 }
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800209
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800210 NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
211 Consumer::OnTimeout(sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800212}
213
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700214void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800215ConsumerWindow::WillSendOutInterest(uint32_t sequenceNumber)
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700216{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800217 m_inFlight++;
218 Consumer::WillSendOutInterest(sequenceNumber);
Alexander Afanasyev79b2fb32013-04-12 11:24:55 -0700219}
220
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700221} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800222} // namespace ns3