blob: 17d0612699a9a7df8fc58b7ba7cc3566df0e36a4 [file] [log] [blame]
Alexander Afanasyevc74a6022011-08-15 20:01:35 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyev08d984e2011-08-13 19:20:22 -07002/*
Ilya Moiseenko956d0542012-01-02 15:26:40 -08003 * Copyright (c) 2011 University of California, Los Angeles
Alexander Afanasyev08d984e2011-08-13 19:20:22 -07004 *
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 *
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070018 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070019 *
20 */
21
Alexander Afanasyev98256102011-08-14 01:00:02 -070022#include "ccnx-face.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070023
Alexander Afanasyev19426ef2011-11-23 20:55:28 -080024#include "ns3/packet.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070025#include "ns3/log.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070026#include "ns3/node.h"
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070027#include "ns3/assert.h"
Alexander Afanasyevcbe92ae2011-12-16 13:06:18 -080028#include "ns3/uinteger.h"
29#include "ns3/double.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070030
Alexander Afanasyev23d2b542011-12-07 18:54:46 -080031#include <boost/ref.hpp>
32
Alexander Afanasyev98256102011-08-14 01:00:02 -070033NS_LOG_COMPONENT_DEFINE ("CcnxFace");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070034
35namespace ns3 {
36
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080037TypeId
38CcnxFace::GetTypeId ()
39{
40 static TypeId tid = TypeId ("ns3::CcnxFace")
41 .SetParent<Object> ()
42 .SetGroupName ("Ccnx")
Alexander Afanasyevcbe92ae2011-12-16 13:06:18 -080043 .AddAttribute ("Id", "Face id (unique integer for the CCNx stack on this node)",
44 TypeId::ATTR_GET, // allow only getting it.
45 UintegerValue (0),
46 MakeUintegerAccessor (&CcnxFace::m_id),
47 MakeUintegerChecker<uint32_t> ())
48
49 .AddAttribute ("BucketMax", "Maximum size of leaky bucket",
50 DoubleValue (-1.0),
51 MakeDoubleAccessor (&CcnxFace::m_bucketMax),
52 MakeDoubleChecker<double> ())
53 .AddAttribute ("BucketLeak", "Normalized bucket leak size",
54 DoubleValue (0.0),
55 MakeDoubleAccessor (&CcnxFace::m_bucketLeak),
56 MakeDoubleChecker<double> ())
57
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080058 ;
59 return tid;
60}
61
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070062/**
Alexander Afanasyev98256102011-08-14 01:00:02 -070063 * By default, Ccnx face are created in the "down" state
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070064 * with no IP addresses. Before becoming useable, the user must
65 * invoke SetUp on them once an Ccnx address and mask have been set.
66 */
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -080067CcnxFace::CcnxFace (Ptr<Node> node)
Alexander Afanasyev19426ef2011-11-23 20:55:28 -080068 : m_node (node)
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -080069 , m_bucket (0.0)
70 , m_bucketMax (-1.0)
71 , m_bucketLeak (0.0)
72 , m_protocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ())
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070073 , m_ifup (false)
74 , m_id ((uint32_t)-1)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070075{
76 NS_LOG_FUNCTION (this);
Alexander Afanasyev19426ef2011-11-23 20:55:28 -080077
78 NS_ASSERT_MSG (node != 0, "node cannot be NULL. Check the code");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070079}
80
Alexander Afanasyev98256102011-08-14 01:00:02 -070081CcnxFace::~CcnxFace ()
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070082{
83 NS_LOG_FUNCTION_NOARGS ();
84}
85
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070086CcnxFace::CcnxFace (const CcnxFace &)
87{
88}
89
90CcnxFace& CcnxFace::operator= (const CcnxFace &)
91{
92 return *this;
93}
94
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -080095void
96CcnxFace::RegisterProtocolHandler (ProtocolHandler handler)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070097{
Alexander Afanasyev19426ef2011-11-23 20:55:28 -080098 NS_LOG_FUNCTION_NOARGS ();
99
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800100 m_protocolHandler = handler;
101}
102
103bool
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800104CcnxFace::IsBelowLimit ()
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800105{
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800106 NS_LOG_FUNCTION_NOARGS ();
107
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800108 /// \todo Implement tracing, if requested
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -0800109
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800110 if (!IsUp ())
111 return false;
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800112
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800113 if (m_bucketMax > 0)
114 {
Alexander Afanasyeve67a97f2011-11-29 14:28:59 -0800115 //NS_LOG_DEBUG ("Limits enabled: " << m_bucketMax << ", current: " << m_bucket);
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800116 if (m_bucket+1.0 > m_bucketMax)
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800117 {
Alexander Afanasyeve67a97f2011-11-29 14:28:59 -0800118 //NS_LOG_DEBUG ("Returning false");
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800119 return false;
120 }
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800121
122 m_bucket += 1.0;
123 }
124
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800125 return true;
126}
127
128bool
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800129CcnxFace::Send (Ptr<Packet> packet)
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800130{
Alexander Afanasyev23d2b542011-12-07 18:54:46 -0800131 NS_LOG_FUNCTION (boost::cref (*this) << packet << packet->GetSize ());
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800132
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800133 /// \todo Implement tracing, if requested
134
135 if (!IsUp ())
136 return false;
137
138 SendImpl (packet);
139 return true;
140}
141
142bool
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800143CcnxFace::Receive (const Ptr<const Packet> &packet)
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800144{
Alexander Afanasyev23d2b542011-12-07 18:54:46 -0800145 NS_LOG_FUNCTION (boost::cref (*this) << packet << packet->GetSize ());
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800146
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800147 /// \todo Implement tracing, if requested
148
149 if (!IsUp ())
150 return false;
151
152 m_protocolHandler (this, packet);
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800153
154 return true;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700155}
156
Alexander Afanasyevcbe92ae2011-12-16 13:06:18 -0800157void
158CcnxFace::LeakBucket (const Time &interval)
159{
160 const double leak = m_bucketLeak * interval.ToDouble (Time::S);
161 m_bucket = std::max (0.0, m_bucket - leak);
162
163 // NS_LOG_DEBUG ("max: " << m_bucketMax << ", Current bucket: " << m_bucket << ", leak size: " << leak << ", interval: " << interval << ", " << m_bucketLeak);
164}
165
166void
167CcnxFace::SetBucketMax (double bucket)
168{
169 NS_LOG_FUNCTION (this << bucket);
170 m_bucketMax = bucket;
171}
172
173void
174CcnxFace::SetBucketLeak (double leak)
175{
176 NS_LOG_FUNCTION (this << leak);
177 m_bucketLeak = leak;
178}
179
180void
181CcnxFace::LeakBucketByOnePacket ()
182{
183 m_bucket = std::max (0.0, m_bucket-1.0);
184}
185
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700186// void
187// CcnxFace::SetMetric (uint16_t metric)
188// {
189// NS_LOG_FUNCTION (metric);
190// m_metric = metric;
191// }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700192
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700193// uint16_t
194// CcnxFace::GetMetric (void) const
195// {
196// NS_LOG_FUNCTION_NOARGS ();
197// return m_metric;
198// }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700199
200/**
Alexander Afanasyev98256102011-08-14 01:00:02 -0700201 * These are face states and may be distinct from
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700202 * NetDevice states, such as found in real implementations
Alexander Afanasyev98256102011-08-14 01:00:02 -0700203 * (where the device may be down but face state is still up).
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700204 */
205bool
Alexander Afanasyev98256102011-08-14 01:00:02 -0700206CcnxFace::IsUp (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700207{
208 NS_LOG_FUNCTION_NOARGS ();
209 return m_ifup;
210}
211
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700212void
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800213CcnxFace::SetUp (bool up/* = true*/)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700214{
215 NS_LOG_FUNCTION_NOARGS ();
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800216 m_ifup = up;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700217}
218
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700219bool
220CcnxFace::operator== (const CcnxFace &face) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700221{
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800222 NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
223 "Faces of different nodes should not be compared to each other");
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700224
225 return (m_id == face.m_id);
226}
227
228bool
229CcnxFace::operator< (const CcnxFace &face) const
230{
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800231 NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
232 "Faces of different nodes should not be compared to each other");
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700233
234 return (m_id < face.m_id);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700235}
236
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700237std::ostream&
238CcnxFace::Print (std::ostream &os) const
239{
240 os << "id=" << GetId ();
241 return os;
242}
243
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700244std::ostream& operator<< (std::ostream& os, const CcnxFace &face)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700245{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700246 face.Print (os);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700247 return os;
248}
249
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700250}; // namespace ns3
251