blob: f214a9e7aa059289fd4a7ce9ae3af2183bbcaebf [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 Afanasyev4aac5572012-08-09 10:49:55 -070021#include "ndn-consumer-window.h"
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 Afanasyev2b4c9472012-08-09 15:00:38 -070031NS_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 Afanasyev2b4c9472012-08-09 15:00:38 -070036NS_OBJECT_ENSURE_REGISTERED (ConsumerWindow);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080037
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080038TypeId
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070039ConsumerWindow::GetTypeId (void)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080040{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070041 static TypeId tid = TypeId ("ns3::ndn::ConsumerWindow")
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070042 .SetGroupName ("Ndn")
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070043 .SetParent<Consumer> ()
44 .AddConstructor<ConsumerWindow> ()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080045
46 .AddAttribute ("Window", "Initial size of the window",
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -080047 StringValue ("1"),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070048 MakeUintegerAccessor (&ConsumerWindow::GetWindow, &ConsumerWindow::SetWindow),
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080049 MakeUintegerChecker<uint32_t> ())
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080050
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080051 .AddAttribute ("PayloadSize", "Average size of content object size (to calculate interest generation rate)",
52 UintegerValue (1040),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070053 MakeUintegerAccessor (&ConsumerWindow::GetPayloadSize, &ConsumerWindow::SetPayloadSize),
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080054 MakeUintegerChecker<uint32_t>())
55 .AddAttribute ("Size", "Amount of data in megabytes to request (relies on PayloadSize parameter)",
56 DoubleValue (-1), // don't impose limit by default
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070057 MakeDoubleAccessor (&ConsumerWindow::GetMaxSize, &ConsumerWindow::SetMaxSize),
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080058 MakeDoubleChecker<double> ())
59
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080060 .AddAttribute ("InitialWindowOnTimeout", "Set window to initial value when timeout occurs",
61 BooleanValue (true),
62 MakeBooleanAccessor (&ConsumerWindow::m_setInitialWindowOnTimeout),
63 MakeBooleanChecker ())
64
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080065 .AddTraceSource ("WindowTrace",
66 "Window that controls how many outstanding interests are allowed",
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070067 MakeTraceSourceAccessor (&ConsumerWindow::m_window))
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -080068 .AddTraceSource ("InFlight",
69 "Current number of outstanding interests",
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070070 MakeTraceSourceAccessor (&ConsumerWindow::m_window))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080071 ;
72
73 return tid;
74}
75
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070076ConsumerWindow::ConsumerWindow ()
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080077 : m_payloadSize (1040)
78 , m_inFlight (0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080079{
80}
81
82void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070083ConsumerWindow::SetWindow (uint32_t window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080084{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080085 m_initialWindow = window;
86 m_window = m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080087}
88
89uint32_t
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070090ConsumerWindow::GetWindow () const
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080091{
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -080092 return m_initialWindow;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080093}
94
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080095uint32_t
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070096ConsumerWindow::GetPayloadSize () const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080097{
98 return m_payloadSize;
99}
100
101void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700102ConsumerWindow::SetPayloadSize (uint32_t payload)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800103{
104 m_payloadSize = payload;
105}
106
107double
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700108ConsumerWindow::GetMaxSize () const
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800109{
110 if (m_seqMax == 0)
111 return -1.0;
112
113 return m_maxSize;
114}
115
116void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700117ConsumerWindow::SetMaxSize (double size)
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800118{
119 m_maxSize = size;
120 if (m_maxSize < 0)
121 {
122 m_seqMax = 0;
123 return;
124 }
125
126 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
127 NS_LOG_DEBUG ("MaxSeqNo: " << m_seqMax);
Alexander Afanasyev1180b042012-01-25 19:26:13 -0800128 // std::cout << "MaxSeqNo: " << m_seqMax << "\n";
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -0800129}
130
131
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800132void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700133ConsumerWindow::ScheduleNextPacket ()
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800134{
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800135 if (m_window == static_cast<uint32_t> (0))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800136 {
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800137 Simulator::Remove (m_sendEvent);
138
139 NS_LOG_DEBUG ("Next event in " << (std::min<double> (0.5, m_rtt->RetransmitTimeout ().ToDouble (Time::S))) << " sec");
140 m_sendEvent = Simulator::Schedule (Seconds (std::min<double> (0.5, m_rtt->RetransmitTimeout ().ToDouble (Time::S))),
141 &Consumer::SendPacket, this);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800142 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800143 else if (m_inFlight >= m_window)
144 {
145 // simply do nothing
146 }
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800147 else
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800148 {
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800149 if (m_sendEvent.IsRunning ())
150 {
151 Simulator::Remove (m_sendEvent);
152 }
153
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800154 // NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800155 m_inFlight++;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700156 m_sendEvent = Simulator::ScheduleNow (&Consumer::SendPacket, this);
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800157 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800158}
159
160///////////////////////////////////////////////////
161// Process incoming packets //
162///////////////////////////////////////////////////
163
164void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700165ConsumerWindow::OnContentObject (const Ptr<const ContentObjectHeader> &contentObject,
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800166 Ptr<Packet> payload)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800167{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700168 Consumer::OnContentObject (contentObject, payload);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800169
170 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800171
172 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyeve1b2a2d2012-11-16 11:53:42 -0800173 NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
174
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800175 ScheduleNextPacket ();
176}
177
178void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700179ConsumerWindow::OnNack (const Ptr<const InterestHeader> &interest, Ptr<Packet> payload)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800180{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700181 Consumer::OnNack (interest, payload);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800182
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800183 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800184
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800185 if (m_window > static_cast<uint32_t> (0))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800186 {
187 // m_window = 0.5 * m_window;//m_window - 1;
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800188 m_window = std::max<uint32_t> (0, m_window - 1);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800189 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800190
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800191 NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
192
193 ScheduleNextPacket ();
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800194}
195
196void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700197ConsumerWindow::OnTimeout (uint32_t sequenceNumber)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800198{
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800199 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyevd1f7c7b2013-01-31 13:34:37 -0800200
201 if (m_setInitialWindowOnTimeout)
202 {
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
207 NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700208 Consumer::OnTimeout (sequenceNumber);
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800209}
210
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700211} // namespace ndn
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800212} // namespace ns3