blob: a408dc4e15573a427d7f4bda582dd6022b96052f [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 Afanasyev4aac5572012-08-09 10:49:55 -070022#include "ndn-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 Afanasyev8e0d2812012-01-19 22:38:14 -080030#include "ns3/boolean.h"
Alexander Afanasyev4975f732011-12-20 17:52:19 -080031#include "ns3/simulator.h"
Alexander Afanasyev98d85e12012-08-09 10:06:05 -070032#include "ns3/random-variable.h"
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070033#include "ns3/pointer.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070034
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -070035#include "ns3/ndn-header-helper.h"
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -080036#include "ns3/ndnSIM/utils/ndn-fw-hop-count-tag.h"
Alexander Afanasyevb989b122013-07-10 17:15:46 -070037#include "ns3/ndnSIM/model/wire/ndnsim.h"
Alexander Afanasyeva89bc102013-07-16 10:17:31 -070038#include "ns3/ndnSIM/model/wire/ndnsim/wire-ndnsim.h"
Alexander Afanasyev5ab2bcd2013-07-15 18:21:19 -070039#include "ns3/ndnSIM/model/wire/ccnb.h"
Alexander Afanasyeva89bc102013-07-16 10:17:31 -070040#include "ns3/ndnSIM/model/wire/ccnb/wire-ccnb.h"
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -080041
Alexander Afanasyev23d2b542011-12-07 18:54:46 -080042#include <boost/ref.hpp>
43
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070044NS_LOG_COMPONENT_DEFINE ("ndn.Face");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070045
46namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070047namespace ndn {
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070048
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070049NS_OBJECT_ENSURE_REGISTERED (Face);
Alexander Afanasyev30c33e32012-06-05 21:28:44 -070050
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080051TypeId
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070052Face::GetTypeId ()
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080053{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070054 static TypeId tid = TypeId ("ns3::ndn::Face")
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080055 .SetParent<Object> ()
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070056 .SetGroupName ("Ndn")
57 .AddAttribute ("Id", "Face id (unique integer for the Ndn stack on this node)",
Alexander Afanasyevcbe92ae2011-12-16 13:06:18 -080058 TypeId::ATTR_GET, // allow only getting it.
59 UintegerValue (0),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070060 MakeUintegerAccessor (&Face::m_id),
Alexander Afanasyevcbe92ae2011-12-16 13:06:18 -080061 MakeUintegerChecker<uint32_t> ())
Alexander Afanasyev5ab2bcd2013-07-15 18:21:19 -070062
63 .AddAttribute ("WireFormat",
64 "Default wire format for the face. The face will be accepting packets "
65 "in any supported packet formats, but if encoding requested, it will "
66 "use default wire format to encode (0 for ndnSIM (default), 1 for CCNb)",
67 UintegerValue (WIRE_FORMAT_NDNSIM),
68 MakeUintegerAccessor (&Face::m_wireFormat),
69 MakeUintegerChecker<uint32_t> ())
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080070 ;
71 return tid;
72}
73
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -080074/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070075 * By default, Ndn face are created in the "down" state
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -080076 * with no IP addresses. Before becoming useable, the user must
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070077 * invoke SetUp on them once an Ndn address and mask have been set.
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070078 */
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -080079Face::Face (Ptr<Node> node)
Alexander Afanasyev19426ef2011-11-23 20:55:28 -080080 : m_node (node)
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -070081 , m_upstreamInterestHandler (MakeNullCallback< void, Ptr<Face>, Ptr<Interest> > ())
82 , m_upstreamDataHandler (MakeNullCallback< void, Ptr<Face>, Ptr<ContentObject> > ())
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070083 , m_ifup (false)
84 , m_id ((uint32_t)-1)
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -080085 , m_metric (0)
Alexander Afanasyevdd9fa4f2013-05-15 16:35:04 -070086 , m_flags (0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070087{
88 NS_LOG_FUNCTION (this);
Alexander Afanasyev19426ef2011-11-23 20:55:28 -080089
90 NS_ASSERT_MSG (node != 0, "node cannot be NULL. Check the code");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070091}
92
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070093Face::~Face ()
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070094{
95 NS_LOG_FUNCTION_NOARGS ();
96}
97
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070098Face::Face (const Face &)
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070099{
100}
101
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700102Face& Face::operator= (const Face &)
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700103{
104 return *this;
105}
106
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800107Ptr<Node>
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700108Face::GetNode () const
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800109{
110 return m_node;
111}
112
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800113void
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700114Face::RegisterProtocolHandlers (const InterestHandler &interestHandler, const DataHandler &dataHandler)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700115{
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800116 NS_LOG_FUNCTION_NOARGS ();
117
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700118 m_upstreamInterestHandler = interestHandler;
119 m_upstreamDataHandler = dataHandler;
120}
121
122void
123Face::UnRegisterProtocolHandlers ()
124{
125 NS_LOG_FUNCTION_NOARGS ();
126
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700127 m_upstreamInterestHandler = MakeNullCallback< void, Ptr<Face>, Ptr<Interest> > ();
128 m_upstreamDataHandler = MakeNullCallback< void, Ptr<Face>, Ptr<ContentObject> > ();
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700129}
130
131
132bool
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700133Face::SendInterest (Ptr<const Interest> interest)
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700134{
Alexander Afanasyeve4795ae2013-07-11 20:01:31 -0700135 NS_LOG_FUNCTION (this << boost::cref (*this) << interest->GetName ());
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700136
137 if (!IsUp ())
138 {
139 return false;
140 }
141
Alexander Afanasyev5ab2bcd2013-07-15 18:21:19 -0700142 Ptr<Packet> packet;
143 if (m_wireFormat == WIRE_FORMAT_NDNSIM)
144 packet = wire::ndnSIM::Interest::ToWire (interest);
145 else if (m_wireFormat == WIRE_FORMAT_CCNB)
146 packet = wire::ccnb::Interest::ToWire (interest);
147 else
148 {
149 NS_FATAL_ERROR ("Unsupported format requested");
150 }
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700151 return Send (packet);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700152}
153
154bool
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700155Face::SendData (Ptr<const ContentObject> data)
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700156{
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700157 NS_LOG_FUNCTION (this << data);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700158
159 if (!IsUp ())
160 {
161 return false;
162 }
163
Alexander Afanasyev5ab2bcd2013-07-15 18:21:19 -0700164 Ptr<Packet> packet;
165 if (m_wireFormat == WIRE_FORMAT_NDNSIM)
166 packet = wire::ndnSIM::Data::ToWire (data);
167 else if (m_wireFormat == WIRE_FORMAT_CCNB)
168 packet = wire::ccnb::Data::ToWire (data);
169 else
170 {
171 NS_FATAL_ERROR ("Unsupported format requested");
172 }
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700173 return Send (packet);
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800174}
175
176bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700177Face::Send (Ptr<Packet> packet)
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800178{
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800179 FwHopCountTag hopCount;
180 bool tagExists = packet->RemovePacketTag (hopCount);
181 if (tagExists)
182 {
183 hopCount.Increment ();
184 packet->AddPacketTag (hopCount);
185 }
Alexander Afanasyev30c33e32012-06-05 21:28:44 -0700186
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700187 return true;
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800188}
189
190bool
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700191Face::Receive (Ptr<const Packet> p)
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800192{
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700193 NS_LOG_FUNCTION (this << p << p->GetSize ());
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800194
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800195 if (!IsUp ())
Alexander Afanasyev30c33e32012-06-05 21:28:44 -0700196 {
197 // no tracing here. If we were off while receiving, we shouldn't even know that something was there
198 return false;
199 }
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800200
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700201 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
202 try
203 {
204 HeaderHelper::Type type = HeaderHelper::GetNdnHeaderType (packet);
205 switch (type)
206 {
207 case HeaderHelper::INTEREST_NDNSIM:
208 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700209 Ptr<Interest> interest = wire::ndnSIM::Interest::FromWire (packet);
210 return ReceiveInterest (interest);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700211 }
212 case HeaderHelper::CONTENT_OBJECT_NDNSIM:
213 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700214 Ptr<ContentObject> data = wire::ndnSIM::Data::FromWire (packet);
215 return ReceiveData (data);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700216 }
217 case HeaderHelper::INTEREST_CCNB:
Alexander Afanasyev5ab2bcd2013-07-15 18:21:19 -0700218 {
219 Ptr<Interest> interest = wire::ccnb::Interest::FromWire (packet);
220 return ReceiveInterest (interest);
221 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700222 case HeaderHelper::CONTENT_OBJECT_CCNB:
Alexander Afanasyev5ab2bcd2013-07-15 18:21:19 -0700223 {
224 Ptr<ContentObject> data = wire::ccnb::Data::FromWire (packet);
225 return ReceiveData (data);
226 }
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700227 }
228
229 // exception will be thrown if packet is not recognized
230 }
231 catch (UnknownHeaderException)
232 {
233 NS_ASSERT_MSG (false, "Unknown NDN header. Should not happen");
234 NS_LOG_ERROR ("Unknown NDN header. Should not happen");
235 return false;
236 }
237}
238
239bool
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700240Face::ReceiveInterest (Ptr<Interest> interest)
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700241{
242 if (!IsUp ())
243 {
244 // no tracing here. If we were off while receiving, we shouldn't even know that something was there
245 return false;
246 }
247
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700248 m_upstreamInterestHandler (this, interest);
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700249 return true;
250}
251
252bool
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700253Face::ReceiveData (Ptr<ContentObject> data)
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700254{
255 if (!IsUp ())
256 {
257 // no tracing here. If we were off while receiving, we shouldn't even know that something was there
258 return false;
259 }
260
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700261 m_upstreamDataHandler (this, data);
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800262 return true;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700263}
264
Alexander Afanasyevcbe92ae2011-12-16 13:06:18 -0800265void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700266Face::SetMetric (uint16_t metric)
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800267{
268 NS_LOG_FUNCTION (metric);
269 m_metric = metric;
270}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700271
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800272uint16_t
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700273Face::GetMetric (void) const
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800274{
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800275 return m_metric;
276}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700277
Alexander Afanasyevdd9fa4f2013-05-15 16:35:04 -0700278void
279Face::SetFlags (uint32_t flags)
280{
281 m_flags = flags;
282}
283
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700284bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700285Face::operator== (const Face &face) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700286{
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800287 NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800288 "Faces of different nodes should not be compared to each other: " << *this << " == " << face);
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700289
290 return (m_id == face.m_id);
291}
292
293bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700294Face::operator< (const Face &face) const
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700295{
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800296 NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
Alexander Afanasyev91d7c7c2013-01-31 15:01:08 -0800297 "Faces of different nodes should not be compared to each other: " << *this << " == " << face);
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700298
299 return (m_id < face.m_id);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700300}
301
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700302std::ostream&
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700303Face::Print (std::ostream &os) const
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700304{
305 os << "id=" << GetId ();
306 return os;
307}
308
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700309std::ostream&
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700310operator<< (std::ostream& os, const Face &face)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700311{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700312 face.Print (os);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700313 return os;
314}
315
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700316uint32_t
317Face::NameToWireSize (Ptr<Name> name) const
318{
319 if (m_wireFormat == WIRE_FORMAT_NDNSIM)
320 return wire::NdnSim::SerializedSizeName (*name);
321 else if (m_wireFormat == WIRE_FORMAT_CCNB)
322 return wire::Ccnb::SerializedSizeName (*name);
323 else
324 {
325 NS_FATAL_ERROR ("Unsupported format requested");
326 }
327 return 0;
328}
329
330/**
331 * @brief Convert name to wire format
332 */
333void
334Face::NameToWire (Buffer::Iterator start, Ptr<const Name> name) const
335{
336 if (m_wireFormat == WIRE_FORMAT_NDNSIM)
337 wire::NdnSim::SerializedSizeName (*name);
338 else if (m_wireFormat == WIRE_FORMAT_CCNB)
339 wire::Ccnb::SerializedSizeName (*name);
340 else
341 {
342 NS_FATAL_ERROR ("Unsupported format requested");
343 }
344}
345
346/**
347 * @brief Convert name from wire format
348 */
349Ptr<Name>
350Face::NameFromWire (Buffer::Iterator start) const
351{
352 if (m_wireFormat == WIRE_FORMAT_NDNSIM)
353 return wire::NdnSim::DeserializeName (start);
354 else if (m_wireFormat == WIRE_FORMAT_CCNB)
355 {
356 return wire::Ccnb::DeserializeName (start);
357 }
358 else
359 {
360 NS_FATAL_ERROR ("Unsupported format requested");
361 }
362 return 0;
363}
364
365
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700366} // namespace ndn
367} // namespace ns3
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700368