blob: 1dd836973151e990f3a88f7956f20e0d31beab33 [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
21#include "ccnx-consumer-window.h"
22#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
31NS_LOG_COMPONENT_DEFINE ("CcnxConsumerWindow");
32
33namespace ns3
34{
35
36NS_OBJECT_ENSURE_REGISTERED (CcnxConsumerWindow);
37
38TypeId
39CcnxConsumerWindow::GetTypeId (void)
40{
41 static TypeId tid = TypeId ("ns3::CcnxConsumerWindow")
42 .SetParent<CcnxConsumer> ()
43 .AddConstructor<CcnxConsumerWindow> ()
44
45 .AddAttribute ("Window", "Initial size of the window",
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -080046 StringValue ("1"),
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080047 MakeUintegerAccessor (&CcnxConsumerWindow::GetWindow, &CcnxConsumerWindow::SetWindow),
48 MakeUintegerChecker<uint32_t> ())
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080049
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080050 .AddAttribute ("PayloadSize", "Average size of content object size (to calculate interest generation rate)",
51 UintegerValue (1040),
52 MakeUintegerAccessor (&CcnxConsumerWindow::GetPayloadSize, &CcnxConsumerWindow::SetPayloadSize),
53 MakeUintegerChecker<uint32_t>())
54 .AddAttribute ("Size", "Amount of data in megabytes to request (relies on PayloadSize parameter)",
55 DoubleValue (-1), // don't impose limit by default
56 MakeDoubleAccessor (&CcnxConsumerWindow::GetMaxSize, &CcnxConsumerWindow::SetMaxSize),
57 MakeDoubleChecker<double> ())
58
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080059 .AddTraceSource ("WindowTrace",
60 "Window that controls how many outstanding interests are allowed",
61 MakeTraceSourceAccessor (&CcnxConsumerWindow::m_window))
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -080062 .AddTraceSource ("InFlight",
63 "Current number of outstanding interests",
64 MakeTraceSourceAccessor (&CcnxConsumerWindow::m_window))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080065 ;
66
67 return tid;
68}
69
70CcnxConsumerWindow::CcnxConsumerWindow ()
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080071 : m_payloadSize (1040)
72 , m_inFlight (0)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -080073{
74}
75
76void
77CcnxConsumerWindow::SetWindow (uint32_t window)
78{
79 m_window = window;
80}
81
82uint32_t
83CcnxConsumerWindow::GetWindow () const
84{
85 return m_window;
86}
87
Alexander Afanasyevb7ad2322012-01-17 22:54:49 -080088uint32_t
89CcnxConsumerWindow::GetPayloadSize () const
90{
91 return m_payloadSize;
92}
93
94void
95CcnxConsumerWindow::SetPayloadSize (uint32_t payload)
96{
97 m_payloadSize = payload;
98}
99
100double
101CcnxConsumerWindow::GetMaxSize () const
102{
103 if (m_seqMax == 0)
104 return -1.0;
105
106 return m_maxSize;
107}
108
109void
110CcnxConsumerWindow::SetMaxSize (double size)
111{
112 m_maxSize = size;
113 if (m_maxSize < 0)
114 {
115 m_seqMax = 0;
116 return;
117 }
118
119 m_seqMax = floor(1.0 + m_maxSize * 1024.0 * 1024.0 / m_payloadSize);
120 NS_LOG_DEBUG ("MaxSeqNo: " << m_seqMax);
121}
122
123
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800124void
125CcnxConsumerWindow::ScheduleNextPacket ()
126{
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800127 if (m_window == static_cast<uint32_t> (0) || m_inFlight >= m_window)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800128 {
129 if (!m_sendEvent.IsRunning ())
130 m_sendEvent = Simulator::Schedule (Seconds (m_rtt->RetransmitTimeout ().ToDouble (Time::S) * 0.1), &CcnxConsumer::SendPacket, this);
131 return;
132 }
133
134 // std::cout << "Window: " << m_window << ", InFlight: " << m_inFlight << "\n";
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800135 if (!m_sendEvent.IsRunning ())
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800136 {
137 m_inFlight++;
138 m_sendEvent = Simulator::ScheduleNow (&CcnxConsumer::SendPacket, this);
139 }
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800140}
141
142///////////////////////////////////////////////////
143// Process incoming packets //
144///////////////////////////////////////////////////
145
146void
147CcnxConsumerWindow::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800148 Ptr<Packet> payload)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800149{
150 CcnxConsumer::OnContentObject (contentObject, payload);
151
152 m_window = m_window + 1;
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800153
154 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800155 ScheduleNextPacket ();
156}
157
158void
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800159CcnxConsumerWindow::OnNack (const Ptr<const CcnxInterestHeader> &interest, Ptr<Packet> payload)
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800160{
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800161 CcnxConsumer::OnNack (interest, payload);
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800162 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800163
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800164 if (m_window > static_cast<uint32_t> (0))
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800165 {
166 // m_window = 0.5 * m_window;//m_window - 1;
167 m_window = m_window - 1;
168 }
169}
170
171void
172CcnxConsumerWindow::OnTimeout (uint32_t sequenceNumber)
173{
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800174 if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800175 CcnxConsumer::OnTimeout (sequenceNumber);
176}
177
178} // namespace ns3