blob: 19161045858b2b1253dbdb247963b7396920f8b2 [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"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080026#include "ns3/string.h"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080027#include "ns3/point-to-point-net-device.h"
28
29#include "model/ndn-l3-protocol.hpp"
30#include "model/ndn-net-device-face.hpp"
31#include "utils/ndn-time.hpp"
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080032#include "utils/dummy-keychain.hpp"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080033#include "model/cs/ndn-content-store.hpp"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070034
35#include <limits>
36#include <map>
Alexander Afanasyevb7626842012-01-12 13:43:33 -080037#include <boost/lexical_cast.hpp>
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080038
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080039NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070040
41namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070042namespace ndn {
Alexander Afanasyev122f3782013-02-02 00:04:40 -080043
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080044StackHelper::StackHelper()
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080045 : m_needSetDefaultRoutes(false)
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080046 , m_shouldUseNfdCs(true)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070047{
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080048 setCustomNdnCxxClocks();
49
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050 m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080051 m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
Alexander Afanasyev122f3782013-02-02 00:04:40 -080052
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080053 m_netDeviceCallbacks.push_back(
54 std::make_pair(PointToPointNetDevice::GetTypeId(),
55 MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
Alexander Afanasyev122f3782013-02-02 00:04:40 -080056 // default callback will be fired if non of others callbacks fit or did the job
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070057}
Alexander Afanasyev122f3782013-02-02 00:04:40 -080058
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059StackHelper::~StackHelper()
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070060{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070061}
62
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080063KeyChain&
64StackHelper::getKeyChain()
65{
66 static ::ndn::DummyKeyChain keyChain;
67 return keyChain;
68}
69
Alexander Afanasyev3a4a0b32012-06-28 14:14:22 -070070void
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080071StackHelper::setCustomNdnCxxClocks()
72{
73 ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
74 make_shared<ns3::ndn::time::CustomSystemClock>());
75}
76
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080077void
78StackHelper::SetDefaultRoutes(bool needSet)
79{
80 NS_LOG_FUNCTION(this << needSet);
81 m_needSetDefaultRoutes = needSet;
82}
83
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080084void
85StackHelper::SetStackAttributes(const std::string& attr1, const std::string& value1,
86 const std::string& attr2, const std::string& value2,
87 const std::string& attr3, const std::string& value3,
88 const std::string& attr4, const std::string& value4)
89{
90 if (attr1 != "")
91 m_ndnFactory.Set(attr1, StringValue(value1));
92 if (attr2 != "")
93 m_ndnFactory.Set(attr2, StringValue(value2));
94 if (attr3 != "")
95 m_ndnFactory.Set(attr3, StringValue(value3));
96 if (attr4 != "")
97 m_ndnFactory.Set(attr4, StringValue(value4));
98}
99
100void
101StackHelper::SetContentStore(const std::string& contentStore, const std::string& attr1,
102 const std::string& value1, const std::string& attr2,
103 const std::string& value2, const std::string& attr3,
104 const std::string& value3, const std::string& attr4,
105 const std::string& value4)
106{
107 NS_ASSERT_MSG(m_shouldUseNfdCs == false,
108 "First choose not to use NFD's CS and then select the replacement policy");
109
110 m_contentStoreFactory.SetTypeId(contentStore);
111 if (attr1 != "")
112 m_contentStoreFactory.Set(attr1, StringValue(value1));
113 if (attr2 != "")
114 m_contentStoreFactory.Set(attr2, StringValue(value2));
115 if (attr3 != "")
116 m_contentStoreFactory.Set(attr3, StringValue(value3));
117 if (attr4 != "")
118 m_contentStoreFactory.Set(attr4, StringValue(value4));
119}
120
121void
122StackHelper::SetContentStoreChoice(bool shouldUseNfdCs)
123{
124 m_shouldUseNfdCs = shouldUseNfdCs;
125}
126
127bool
128StackHelper::shouldUseNfdCs() const
129{
130 return m_shouldUseNfdCs;
131}
132
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700133Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134StackHelper::Install(const NodeContainer& c) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700135{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 Ptr<FaceContainer> faces = Create<FaceContainer>();
137 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
138 faces->AddAll(Install(*i));
139 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700140 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700141}
142
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700143Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144StackHelper::InstallAll() const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700145{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146 return Install(NodeContainer::GetGlobal());
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700147}
148
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700149Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800150StackHelper::Install(Ptr<Node> node) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700151{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 Ptr<FaceContainer> faces = Create<FaceContainer>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800153
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800154 if (node->GetObject<L3Protocol>() != 0) {
155 NS_FATAL_ERROR("StackHelper::Install (): Installing "
156 "a NdnStack to a node with an existing Ndn object");
157 return 0;
158 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700159
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800161
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800162 // NFD initialization
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800163 ndn->initialize(m_shouldUseNfdCs);
164
165 // Create and aggregate content store if NFD's contest store has been disabled
166 if (!m_shouldUseNfdCs)
167 ndn->AggregateObject(m_contentStoreFactory.Create<ContentStore>());
168
169 // Aggregate L3Protocol on node (must be after setting ndnSIM CS)
170 node->AggregateObject(ndn);
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800171
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800172 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
173 Ptr<NetDevice> device = node->GetDevice(index);
174 // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
175 // Normally, ndnSIM works without IP stack, so no reason to check
176 // if (DynamicCast<LoopbackNetDevice> (device) != 0)
177 // continue; // don't create face for a LoopbackNetDevice
Alexander Afanasyev11453142011-11-25 16:13:33 -0800178
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700179 shared_ptr<NetDeviceFace> face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800180
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800181 for (const auto& item : m_netDeviceCallbacks) {
182 if (device->GetInstanceTypeId() == item.first ||
183 device->GetInstanceTypeId().IsChildOf(item.first)) {
184 face = item.second(node, ndn, device);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800185 if (face != 0)
186 break;
187 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700188 }
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800189
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190 if (face == 0) {
191 face = DefaultNetDeviceCallback(node, ndn, device);
192 }
193
Spyridon Mastorakis588fd102014-11-20 19:50:02 -0800194 if (m_needSetDefaultRoutes) {
195 // default route with lowest priority possible
196 FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
197 }
198
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800199 faces->Add(face);
200 }
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800201
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700202 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700203}
204
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800205void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800206StackHelper::AddNetDeviceFaceCreateCallback(TypeId netDeviceType,
207 StackHelper::NetDeviceFaceCreateCallback callback)
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800208{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800209 m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800210}
211
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700212void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800213StackHelper::UpdateNetDeviceFaceCreateCallback(TypeId netDeviceType,
214 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700215{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800216 for (auto& i : m_netDeviceCallbacks) {
217 if (i.first == netDeviceType) {
218 i.second = callback;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219 return;
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700220 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 }
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700222}
223
224void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800225StackHelper::RemoveNetDeviceFaceCreateCallback(TypeId netDeviceType,
226 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700227{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800228 m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, NetDeviceFaceCreateCallback>& i) {
229 return (i.first == netDeviceType);
230 });
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700231}
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800232
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700233shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800234StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
235 Ptr<NetDevice> netDevice) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800236{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800237 NS_LOG_DEBUG("Creating default NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800238
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800239 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, netDevice);
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800240
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800241 ndn->addFace(face);
242 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
243 << face->getLocalUri());
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800244
245 return face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800246}
247
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700248shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800249StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
250 Ptr<NetDevice> device) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800251{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800252 NS_LOG_DEBUG("Creating point-to-point NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800253
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800254 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, device);
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800255
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800256 ndn->addFace(face);
257 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
258 << face->getLocalUri());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800259
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800260 return face;
261}
262
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700263Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800264StackHelper::Install(const std::string& nodeName) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700265{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800266 Ptr<Node> node = Names::Find<Node>(nodeName);
267 return Install(node);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700268}
269
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700270} // namespace ndn
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700271} // namespace ns3