blob: 2413fb9249c8869ba1a84aca27e55e0b70d455db [file] [log] [blame]
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyev45b92d42011-08-14 23:11:38 -07002/*
3 * Copyright (c) 2011 UCLA
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 *
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070018 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Alexander Afanasyev122f3782013-02-02 00:04:40 -080019 * Ilya Moiseenko <iliamo@cs.ucla.edu>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070020 */
21
Alexander Afanasyev0c395372014-12-20 15:54:02 -080022#include "ndn-stack-helper.hpp"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080023
24#include "ns3/log.h"
25#include "ns3/names.h"
26#include "ns3/point-to-point-net-device.h"
27
28#include "model/ndn-l3-protocol.hpp"
29#include "model/ndn-net-device-face.hpp"
30#include "utils/ndn-time.hpp"
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080031#include "utils/dummy-keychain.hpp"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070032
33#include <limits>
34#include <map>
Alexander Afanasyevb7626842012-01-12 13:43:33 -080035#include <boost/lexical_cast.hpp>
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080036
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080037NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070038
39namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070040namespace ndn {
Alexander Afanasyev122f3782013-02-02 00:04:40 -080041
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042StackHelper::StackHelper()
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080043 : m_needSetDefaultRoutes(false)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070044{
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080045 setCustomNdnCxxClocks();
46
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080047 m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080048 // m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
Alexander Afanasyev122f3782013-02-02 00:04:40 -080049
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050 m_netDeviceCallbacks.push_back(
51 std::make_pair(PointToPointNetDevice::GetTypeId(),
52 MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
Alexander Afanasyev122f3782013-02-02 00:04:40 -080053 // default callback will be fired if non of others callbacks fit or did the job
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070054}
Alexander Afanasyev122f3782013-02-02 00:04:40 -080055
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080056StackHelper::~StackHelper()
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070057{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070058}
59
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080060KeyChain&
61StackHelper::getKeyChain()
62{
63 static ::ndn::DummyKeyChain keyChain;
64 return keyChain;
65}
66
Alexander Afanasyev3a4a0b32012-06-28 14:14:22 -070067void
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080068StackHelper::setCustomNdnCxxClocks()
69{
70 ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
71 make_shared<ns3::ndn::time::CustomSystemClock>());
72}
73
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080074void
75StackHelper::SetDefaultRoutes(bool needSet)
76{
77 NS_LOG_FUNCTION(this << needSet);
78 m_needSetDefaultRoutes = needSet;
79}
80
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070081Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082StackHelper::Install(const NodeContainer& c) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070083{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080084 Ptr<FaceContainer> faces = Create<FaceContainer>();
85 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
86 faces->AddAll(Install(*i));
87 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -070088 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070089}
90
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070091Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092StackHelper::InstallAll() const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070093{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094 return Install(NodeContainer::GetGlobal());
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070095}
96
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070097Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098StackHelper::Install(Ptr<Node> node) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070099{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 Ptr<FaceContainer> faces = Create<FaceContainer>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800101
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800102 if (node->GetObject<L3Protocol>() != 0) {
103 NS_FATAL_ERROR("StackHelper::Install (): Installing "
104 "a NdnStack to a node with an existing Ndn object");
105 return 0;
106 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700107
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108 Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700109 // Aggregate L3Protocol on node
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110 node->AggregateObject(ndn);
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800111
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800112 // NFD initialization
113 ndn->initialize();
114
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
116 Ptr<NetDevice> device = node->GetDevice(index);
117 // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
118 // Normally, ndnSIM works without IP stack, so no reason to check
119 // if (DynamicCast<LoopbackNetDevice> (device) != 0)
120 // continue; // don't create face for a LoopbackNetDevice
Alexander Afanasyev11453142011-11-25 16:13:33 -0800121
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700122 shared_ptr<NetDeviceFace> face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800123
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800124 for (const auto& item : m_netDeviceCallbacks) {
125 if (device->GetInstanceTypeId() == item.first ||
126 device->GetInstanceTypeId().IsChildOf(item.first)) {
127 face = item.second(node, ndn, device);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128 if (face != 0)
129 break;
130 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700131 }
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800132
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 if (face == 0) {
134 face = DefaultNetDeviceCallback(node, ndn, device);
135 }
136
Spyridon Mastorakis588fd102014-11-20 19:50:02 -0800137 if (m_needSetDefaultRoutes) {
138 // default route with lowest priority possible
139 FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
140 }
141
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 faces->Add(face);
143 }
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800144
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700145 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700146}
147
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800148void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149StackHelper::AddNetDeviceFaceCreateCallback(TypeId netDeviceType,
150 StackHelper::NetDeviceFaceCreateCallback callback)
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800151{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800153}
154
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700155void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156StackHelper::UpdateNetDeviceFaceCreateCallback(TypeId netDeviceType,
157 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700158{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800159 for (auto& i : m_netDeviceCallbacks) {
160 if (i.first == netDeviceType) {
161 i.second = callback;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800162 return;
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700163 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800164 }
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700165}
166
167void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800168StackHelper::RemoveNetDeviceFaceCreateCallback(TypeId netDeviceType,
169 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700170{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800171 m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, NetDeviceFaceCreateCallback>& i) {
172 return (i.first == netDeviceType);
173 });
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700174}
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800175
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700176shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
178 Ptr<NetDevice> netDevice) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800179{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800180 NS_LOG_DEBUG("Creating default NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800181
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800182 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, netDevice);
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800183
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800184 ndn->addFace(face);
185 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
186 << face->getLocalUri());
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800187
188 return face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800189}
190
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700191shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
193 Ptr<NetDevice> device) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800194{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800195 NS_LOG_DEBUG("Creating point-to-point NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800196
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800197 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, device);
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800198
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800199 ndn->addFace(face);
200 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
201 << face->getLocalUri());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800203 return face;
204}
205
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700206Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207StackHelper::Install(const std::string& nodeName) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700208{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800209 Ptr<Node> node = Names::Find<Node>(nodeName);
210 return Install(node);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700211}
212
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700213} // namespace ndn
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700214} // namespace ns3