blob: 5e2038c18f9f00e647660c6baee7e1fe37416f38 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -07004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -07007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070019
Alexander Afanasyev0c395372014-12-20 15:54:02 -080020#include "ndn-stack-helper.hpp"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080021
22#include "ns3/log.h"
23#include "ns3/names.h"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080024#include "ns3/string.h"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080025#include "ns3/point-to-point-net-device.h"
26
27#include "model/ndn-l3-protocol.hpp"
28#include "model/ndn-net-device-face.hpp"
29#include "utils/ndn-time.hpp"
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080030#include "utils/dummy-keychain.hpp"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080031#include "model/cs/ndn-content-store.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)
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080044 , m_shouldUseNfdCs(true)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070045{
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080046 setCustomNdnCxxClocks();
47
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080048 m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080049 m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
Alexander Afanasyev122f3782013-02-02 00:04:40 -080050
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080051 m_netDeviceCallbacks.push_back(
52 std::make_pair(PointToPointNetDevice::GetTypeId(),
53 MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
Alexander Afanasyev122f3782013-02-02 00:04:40 -080054 // default callback will be fired if non of others callbacks fit or did the job
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070055}
Alexander Afanasyev122f3782013-02-02 00:04:40 -080056
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057StackHelper::~StackHelper()
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070058{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070059}
60
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080061KeyChain&
62StackHelper::getKeyChain()
63{
64 static ::ndn::DummyKeyChain keyChain;
65 return keyChain;
66}
67
Alexander Afanasyev3a4a0b32012-06-28 14:14:22 -070068void
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080069StackHelper::setCustomNdnCxxClocks()
70{
71 ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
72 make_shared<ns3::ndn::time::CustomSystemClock>());
73}
74
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080075void
76StackHelper::SetDefaultRoutes(bool needSet)
77{
78 NS_LOG_FUNCTION(this << needSet);
79 m_needSetDefaultRoutes = needSet;
80}
81
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080082void
83StackHelper::SetStackAttributes(const std::string& attr1, const std::string& value1,
84 const std::string& attr2, const std::string& value2,
85 const std::string& attr3, const std::string& value3,
86 const std::string& attr4, const std::string& value4)
87{
88 if (attr1 != "")
89 m_ndnFactory.Set(attr1, StringValue(value1));
90 if (attr2 != "")
91 m_ndnFactory.Set(attr2, StringValue(value2));
92 if (attr3 != "")
93 m_ndnFactory.Set(attr3, StringValue(value3));
94 if (attr4 != "")
95 m_ndnFactory.Set(attr4, StringValue(value4));
96}
97
98void
99StackHelper::SetContentStore(const std::string& contentStore, const std::string& attr1,
100 const std::string& value1, const std::string& attr2,
101 const std::string& value2, const std::string& attr3,
102 const std::string& value3, const std::string& attr4,
103 const std::string& value4)
104{
105 NS_ASSERT_MSG(m_shouldUseNfdCs == false,
106 "First choose not to use NFD's CS and then select the replacement policy");
107
108 m_contentStoreFactory.SetTypeId(contentStore);
109 if (attr1 != "")
110 m_contentStoreFactory.Set(attr1, StringValue(value1));
111 if (attr2 != "")
112 m_contentStoreFactory.Set(attr2, StringValue(value2));
113 if (attr3 != "")
114 m_contentStoreFactory.Set(attr3, StringValue(value3));
115 if (attr4 != "")
116 m_contentStoreFactory.Set(attr4, StringValue(value4));
117}
118
119void
120StackHelper::SetContentStoreChoice(bool shouldUseNfdCs)
121{
122 m_shouldUseNfdCs = shouldUseNfdCs;
123}
124
125bool
126StackHelper::shouldUseNfdCs() const
127{
128 return m_shouldUseNfdCs;
129}
130
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700131Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132StackHelper::Install(const NodeContainer& c) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700133{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134 Ptr<FaceContainer> faces = Create<FaceContainer>();
135 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
136 faces->AddAll(Install(*i));
137 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700138 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700139}
140
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700141Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142StackHelper::InstallAll() const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700143{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144 return Install(NodeContainer::GetGlobal());
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700145}
146
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700147Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800148StackHelper::Install(Ptr<Node> node) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700149{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800150 Ptr<FaceContainer> faces = Create<FaceContainer>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800151
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 if (node->GetObject<L3Protocol>() != 0) {
153 NS_FATAL_ERROR("StackHelper::Install (): Installing "
154 "a NdnStack to a node with an existing Ndn object");
155 return 0;
156 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700157
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800159
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800160 // NFD initialization
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800161 ndn->initialize(m_shouldUseNfdCs);
162
163 // Create and aggregate content store if NFD's contest store has been disabled
164 if (!m_shouldUseNfdCs)
165 ndn->AggregateObject(m_contentStoreFactory.Create<ContentStore>());
166
167 // Aggregate L3Protocol on node (must be after setting ndnSIM CS)
168 node->AggregateObject(ndn);
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800169
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800170 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
171 Ptr<NetDevice> device = node->GetDevice(index);
172 // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
173 // Normally, ndnSIM works without IP stack, so no reason to check
174 // if (DynamicCast<LoopbackNetDevice> (device) != 0)
175 // continue; // don't create face for a LoopbackNetDevice
Alexander Afanasyev11453142011-11-25 16:13:33 -0800176
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700177 shared_ptr<NetDeviceFace> face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800178
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800179 for (const auto& item : m_netDeviceCallbacks) {
180 if (device->GetInstanceTypeId() == item.first ||
181 device->GetInstanceTypeId().IsChildOf(item.first)) {
182 face = item.second(node, ndn, device);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183 if (face != 0)
184 break;
185 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700186 }
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800187
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800188 if (face == 0) {
189 face = DefaultNetDeviceCallback(node, ndn, device);
190 }
191
Spyridon Mastorakis588fd102014-11-20 19:50:02 -0800192 if (m_needSetDefaultRoutes) {
193 // default route with lowest priority possible
194 FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
195 }
196
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 faces->Add(face);
198 }
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800199
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700200 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700201}
202
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800203void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204StackHelper::AddNetDeviceFaceCreateCallback(TypeId netDeviceType,
205 StackHelper::NetDeviceFaceCreateCallback callback)
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800206{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800208}
209
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700210void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800211StackHelper::UpdateNetDeviceFaceCreateCallback(TypeId netDeviceType,
212 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700213{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800214 for (auto& i : m_netDeviceCallbacks) {
215 if (i.first == netDeviceType) {
216 i.second = callback;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800217 return;
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700218 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219 }
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700220}
221
222void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800223StackHelper::RemoveNetDeviceFaceCreateCallback(TypeId netDeviceType,
224 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700225{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800226 m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, NetDeviceFaceCreateCallback>& i) {
227 return (i.first == netDeviceType);
228 });
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700229}
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800230
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700231shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800232StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
233 Ptr<NetDevice> netDevice) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800234{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800235 NS_LOG_DEBUG("Creating default NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800236
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800237 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, netDevice);
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800238
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800239 ndn->addFace(face);
240 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
241 << face->getLocalUri());
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800242
243 return face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800244}
245
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700246shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800247StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
248 Ptr<NetDevice> device) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800249{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800250 NS_LOG_DEBUG("Creating point-to-point NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800251
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800252 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, device);
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800253
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800254 ndn->addFace(face);
255 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
256 << face->getLocalUri());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800257
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800258 return face;
259}
260
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700261Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800262StackHelper::Install(const std::string& nodeName) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700263{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800264 Ptr<Node> node = Names::Find<Node>(nodeName);
265 return Install(node);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700266}
267
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700268} // namespace ndn
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700269} // namespace ns3