blob: b66a939b42d8bf705ab17c7f03df7fa97934d210 [file] [log] [blame]
Yanbiao Li73860e32015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi38b24c72017-01-05 02:59:31 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Yanbiao Li73860e32015-08-19 16:30:16 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "face-manager.hpp"
Junxiao Shi40cb61c2015-09-23 18:36:45 -070027#include "face/generic-link-service.hpp"
Junxiao Shib8590312016-12-29 21:22:25 +000028#include "face/protocol-factory.hpp"
Yukai Tu0a49d342015-09-13 12:54:22 +080029#include "fw/face-table.hpp"
Yanbiao Li73860e32015-08-19 16:30:16 -070030
Junxiao Shicbc8e942016-09-06 03:17:45 +000031#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000032#include <ndn-cxx/mgmt/nfd/channel-status.hpp>
Yanbiao Li73860e32015-08-19 16:30:16 -070033
Yanbiao Li73860e32015-08-19 16:30:16 -070034namespace nfd {
35
36NFD_LOG_INIT("FaceManager");
37
Junxiao Shiea47bde2017-01-26 17:49:16 +000038FaceManager::FaceManager(FaceSystem& faceSystem,
39 Dispatcher& dispatcher, CommandAuthenticator& authenticator)
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000040 : NfdManagerBase(dispatcher, authenticator, "faces")
Junxiao Shiea47bde2017-01-26 17:49:16 +000041 , m_faceSystem(faceSystem)
42 , m_faceTable(faceSystem.getFaceTable())
Yanbiao Li73860e32015-08-19 16:30:16 -070043{
Yanbiao Li58ba3f92017-02-15 14:27:18 +000044 // register handlers for ControlCommand
Yanbiao Li73860e32015-08-19 16:30:16 -070045 registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
46 bind(&FaceManager::createFace, this, _2, _3, _4, _5));
47
Eric Newberryb5aa7f52016-09-03 20:36:12 -070048 registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
49 bind(&FaceManager::updateFace, this, _2, _3, _4, _5));
50
Yanbiao Li73860e32015-08-19 16:30:16 -070051 registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
52 bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
53
54 registerCommandHandler<ndn::nfd::FaceEnableLocalControlCommand>("enable-local-control",
55 bind(&FaceManager::enableLocalControl, this, _2, _3, _4, _5));
56
57 registerCommandHandler<ndn::nfd::FaceDisableLocalControlCommand>("disable-local-control",
58 bind(&FaceManager::disableLocalControl, this, _2, _3, _4, _5));
59
Yanbiao Li58ba3f92017-02-15 14:27:18 +000060 // register handlers for StatusDataset
Yanbiao Li73860e32015-08-19 16:30:16 -070061 registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
62 registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
63 registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
64
Yanbiao Li58ba3f92017-02-15 14:27:18 +000065 // register notification stream
Junxiao Shiae04d342016-07-19 13:20:22 +000066 m_postNotification = registerNotificationStream("events");
Eric Newberry1b4ba052016-10-07 23:04:07 -070067 m_faceAddConn = m_faceTable.afterAdd.connect([this] (const Face& face) {
68 connectFaceStateChangeSignal(face);
69 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
70 });
71 m_faceRemoveConn = m_faceTable.beforeRemove.connect([this] (const Face& face) {
72 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
73 });
Yanbiao Li73860e32015-08-19 16:30:16 -070074}
75
76void
77FaceManager::setConfigFile(ConfigFile& configFile)
78{
Junxiao Shib8590312016-12-29 21:22:25 +000079 m_faceSystem.setConfigFile(configFile);
Yanbiao Li73860e32015-08-19 16:30:16 -070080}
81
82void
83FaceManager::createFace(const Name& topPrefix, const Interest& interest,
84 const ControlParameters& parameters,
85 const ndn::mgmt::CommandContinuation& done)
86{
87 FaceUri uri;
88 if (!uri.parse(parameters.getUri())) {
89 NFD_LOG_TRACE("failed to parse URI");
Eric Newberry42602412016-08-27 09:33:18 -070090 done(ControlResponse(400, "Malformed command"));
91 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070092 }
93
94 if (!uri.isCanonical()) {
95 NFD_LOG_TRACE("received non-canonical URI");
Eric Newberry42602412016-08-27 09:33:18 -070096 done(ControlResponse(400, "Non-canonical URI"));
97 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070098 }
99
Junxiao Shi38b24c72017-01-05 02:59:31 +0000100 ProtocolFactory* factory = m_faceSystem.getFactoryByScheme(uri.getScheme());
Junxiao Shib8590312016-12-29 21:22:25 +0000101 if (factory == nullptr) {
Eric Newberry42602412016-08-27 09:33:18 -0700102 NFD_LOG_TRACE("received create request for unsupported protocol");
103 done(ControlResponse(406, "Unsupported protocol"));
104 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700105 }
106
107 try {
Junxiao Shib8590312016-12-29 21:22:25 +0000108 factory->createFace(uri,
109 parameters.getFacePersistency(),
110 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
111 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
112 bind(&FaceManager::afterCreateFaceSuccess, this, parameters, _1, done),
113 bind(&FaceManager::afterCreateFaceFailure, this, _1, _2, done));
Yanbiao Li73860e32015-08-19 16:30:16 -0700114 }
115 catch (const std::runtime_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700116 NFD_LOG_ERROR("Face creation failed: " << error.what());
117 done(ControlResponse(500, "Face creation failed due to internal error"));
118 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700119 }
120 catch (const std::logic_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700121 NFD_LOG_ERROR("Face creation failed: " << error.what());
122 done(ControlResponse(500, "Face creation failed due to internal error"));
123 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700124 }
125}
126
127void
Eric Newberry42602412016-08-27 09:33:18 -0700128FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
Eric Newberryf40551a2016-09-05 15:41:16 -0700129 const shared_ptr<Face>& face,
Yanbiao Li73860e32015-08-19 16:30:16 -0700130 const ndn::mgmt::CommandContinuation& done)
131{
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000132 if (face->getId() != face::INVALID_FACEID) {// Face already exists
133 NFD_LOG_TRACE("Attempted to create duplicate face of " << face->getId());
134
135 ControlParameters response = collectFaceProperties(*face);
136 response.setUri(face->getRemoteUri().toString());
137 done(ControlResponse(409, "Face with remote URI already exists").setBody(response.wireEncode()));
138 return;
139 }
140
Eric Newberryf40551a2016-09-05 15:41:16 -0700141 // If scope non-local and flags set to enable local fields, request shouldn't
142 // have made it this far
143 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
144 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
145 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
146 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
147
148 m_faceTable.add(face);
149
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000150 ControlParameters response = collectFaceProperties(*face);
Eric Newberry42602412016-08-27 09:33:18 -0700151 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
152}
153
154void
155FaceManager::afterCreateFaceFailure(uint32_t status,
156 const std::string& reason,
157 const ndn::mgmt::CommandContinuation& done)
158{
159 NFD_LOG_DEBUG("Face creation failed: " << reason);
160
161 done(ControlResponse(status, reason));
Yanbiao Li73860e32015-08-19 16:30:16 -0700162}
163
164void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700165FaceManager::updateFace(const Name& topPrefix, const Interest& interest,
166 const ControlParameters& parameters,
167 const ndn::mgmt::CommandContinuation& done)
168{
169 FaceId faceId = parameters.getFaceId();
170 if (faceId == 0) {
171 // Self-updating
172 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
173 if (incomingFaceIdTag == nullptr) {
174 NFD_LOG_TRACE("unable to determine face for self-update");
175 done(ControlResponse(404, "No FaceId specified and IncomingFaceId not available"));
176 return;
177 }
178 faceId = *incomingFaceIdTag;
179 }
180
181 Face* face = m_faceTable.get(faceId);
182
183 if (face == nullptr) {
184 NFD_LOG_TRACE("invalid face specified");
185 done(ControlResponse(404, "Specified face does not exist"));
186 return;
187 }
188
189 // Verify validity of requested changes
190 ControlParameters response;
191 bool areParamsValid = true;
192
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700193 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
194 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
195 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
196 NFD_LOG_TRACE("received request to enable local fields on non-local face");
197 areParamsValid = false;
198 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
199 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
200 }
201
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000202 // check whether the requested FacePersistency change is valid if it's present
203 if (parameters.hasFacePersistency()) {
204 auto persistency = parameters.getFacePersistency();
205 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
206 NFD_LOG_TRACE("cannot change face persistency to " << persistency);
207 areParamsValid = false;
208 response.setFacePersistency(persistency);
209 }
210 }
211
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700212 if (!areParamsValid) {
213 done(ControlResponse(409, "Invalid properties specified").setBody(response.wireEncode()));
214 return;
215 }
216
217 // All specified properties are valid, so make changes
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000218 if (parameters.hasFacePersistency()) {
219 face->setPersistency(parameters.getFacePersistency());
220 }
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700221 setLinkServiceOptions(*face, parameters, response);
222
Eric Newberryf40551a2016-09-05 15:41:16 -0700223 // Set ControlResponse fields
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000224 response = collectFaceProperties(*face);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700225
226 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
227}
228
229void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700230FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
231 const ControlParameters& parameters,
232 const ndn::mgmt::CommandContinuation& done)
233{
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000234 Face* face = m_faceTable.get(parameters.getFaceId());
235 if (face != nullptr) {
236 face->close();
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700237 }
238
239 done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
240}
241
242void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700243FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
244 const ControlParameters& parameters,
245 const ndn::mgmt::CommandContinuation& done)
246{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700247 Face* face = findFaceForLocalControl(interest, parameters, done);
248 if (!face) {
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700249 return;
250 }
251
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700252 // enable-local-control will enable all local fields in GenericLinkService
Junxiao Shicde37ad2015-12-24 01:02:05 -0700253 auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700254 if (service == nullptr) {
255 return done(ControlResponse(503, "LinkService type not supported"));
256 }
257
258 face::GenericLinkService::Options options = service->getOptions();
259 options.allowLocalFields = true;
260 service->setOptions(options);
261
262 return done(ControlResponse(200, "OK: enable all local fields on GenericLinkService")
263 .setBody(parameters.wireEncode()));
264}
265
266void
267FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
268 const ControlParameters& parameters,
269 const ndn::mgmt::CommandContinuation& done)
270{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700271 Face* face = findFaceForLocalControl(interest, parameters, done);
272 if (!face) {
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700273 return;
274 }
275
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700276 // disable-local-control will disable all local fields in GenericLinkService
Junxiao Shicde37ad2015-12-24 01:02:05 -0700277 auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700278 if (service == nullptr) {
279 return done(ControlResponse(503, "LinkService type not supported"));
280 }
281
282 face::GenericLinkService::Options options = service->getOptions();
283 options.allowLocalFields = false;
284 service->setOptions(options);
285
286 return done(ControlResponse(200, "OK: disable all local fields on GenericLinkService")
287 .setBody(parameters.wireEncode()));
288}
289
Junxiao Shicde37ad2015-12-24 01:02:05 -0700290Face*
291FaceManager::findFaceForLocalControl(const Interest& request,
292 const ControlParameters& parameters,
293 const ndn::mgmt::CommandContinuation& done)
Yanbiao Li73860e32015-08-19 16:30:16 -0700294{
Junxiao Shi0de23a22015-12-03 20:07:02 +0000295 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
296 // NDNLPv2 says "application MUST be prepared to receive a packet without IncomingFaceId field",
297 // but it's fine to assert IncomingFaceId is available, because InternalFace lives inside NFD
298 // and is initialized synchronously with IncomingFaceId field enabled.
299 BOOST_ASSERT(incomingFaceIdTag != nullptr);
300
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000301 Face* face = m_faceTable.get(*incomingFaceIdTag);
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200302 if (face == nullptr) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000303 NFD_LOG_DEBUG("FaceId " << *incomingFaceIdTag << " not found");
Yanbiao Li73860e32015-08-19 16:30:16 -0700304 done(ControlResponse(410, "Face not found"));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700305 return nullptr;
Yanbiao Li73860e32015-08-19 16:30:16 -0700306 }
307
Junxiao Shicde37ad2015-12-24 01:02:05 -0700308 if (face->getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL) {
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200309 NFD_LOG_DEBUG("Cannot enable local control on non-local FaceId " << face->getId());
Yanbiao Li73860e32015-08-19 16:30:16 -0700310 done(ControlResponse(412, "Face is non-local"));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700311 return nullptr;
Yanbiao Li73860e32015-08-19 16:30:16 -0700312 }
313
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000314 return face;
Yanbiao Li73860e32015-08-19 16:30:16 -0700315}
316
317void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700318FaceManager::setLinkServiceOptions(Face& face,
319 const ControlParameters& parameters,
320 ControlParameters& response)
321{
322 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
323 BOOST_ASSERT(linkService != nullptr);
324
325 auto options = linkService->getOptions();
326 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
327 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
328 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
329 }
330 linkService->setOptions(options);
331
332 // Set Flags for ControlResponse
333 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
334}
335
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000336ControlParameters
337FaceManager::collectFaceProperties(const Face& face)
338{
339 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
340 BOOST_ASSERT(linkService != nullptr);
341 auto options = linkService->getOptions();
342
343 return ControlParameters()
344 .setFaceId(face.getId())
345 .setFacePersistency(face.getPersistency())
346 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
347}
348
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700349void
Yanbiao Li73860e32015-08-19 16:30:16 -0700350FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
351 ndn::mgmt::StatusDatasetContext& context)
352{
Eric Newberryc64d30a2015-12-26 11:07:27 -0700353 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000354 for (const Face& face : m_faceTable) {
355 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700356 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700357 }
358 context.end();
359}
360
361void
362FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
363 ndn::mgmt::StatusDatasetContext& context)
364{
Junxiao Shib8590312016-12-29 21:22:25 +0000365 std::set<const ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
366 for (const ProtocolFactory* factory : factories) {
367 for (const auto& channel : factory->getChannels()) {
368 ndn::nfd::ChannelStatus entry;
369 entry.setLocalUri(channel->getUri().toString());
370 context.append(entry.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700371 }
372 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700373 context.end();
374}
375
376void
377FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
378 ndn::mgmt::StatusDatasetContext& context)
379{
380 ndn::nfd::FaceQueryFilter faceFilter;
381 const Name& query = interest.getName();
382 try {
383 faceFilter.wireDecode(query[-1].blockFromValue());
384 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200385 catch (const tlv::Error& e) {
386 NFD_LOG_DEBUG("Malformed query filter: " << e.what());
387 return context.reject(ControlResponse(400, "Malformed filter"));
Yanbiao Li73860e32015-08-19 16:30:16 -0700388 }
389
Eric Newberryc64d30a2015-12-26 11:07:27 -0700390 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000391 for (const Face& face : m_faceTable) {
392 if (!matchFilter(faceFilter, face)) {
Junxiao Shida93f1f2015-11-11 06:13:16 -0700393 continue;
Yanbiao Li73860e32015-08-19 16:30:16 -0700394 }
Junxiao Shib84e6742016-07-19 13:16:22 +0000395 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700396 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700397 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200398
Yanbiao Li73860e32015-08-19 16:30:16 -0700399 context.end();
400}
401
402bool
Junxiao Shib84e6742016-07-19 13:16:22 +0000403FaceManager::matchFilter(const ndn::nfd::FaceQueryFilter& filter, const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700404{
405 if (filter.hasFaceId() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000406 filter.getFaceId() != static_cast<uint64_t>(face.getId())) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700407 return false;
408 }
409
410 if (filter.hasUriScheme() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000411 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
412 filter.getUriScheme() != face.getLocalUri().getScheme()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700413 return false;
414 }
415
416 if (filter.hasRemoteUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000417 filter.getRemoteUri() != face.getRemoteUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700418 return false;
419 }
420
421 if (filter.hasLocalUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000422 filter.getLocalUri() != face.getLocalUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700423 return false;
424 }
425
426 if (filter.hasFaceScope() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000427 filter.getFaceScope() != face.getScope()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700428 return false;
429 }
430
431 if (filter.hasFacePersistency() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000432 filter.getFacePersistency() != face.getPersistency()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700433 return false;
434 }
435
436 if (filter.hasLinkType() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000437 filter.getLinkType() != face.getLinkType()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700438 return false;
439 }
440
441 return true;
442}
443
Eric Newberryc64d30a2015-12-26 11:07:27 -0700444ndn::nfd::FaceStatus
445FaceManager::collectFaceStatus(const Face& face, const time::steady_clock::TimePoint& now)
446{
447 ndn::nfd::FaceStatus status;
448
449 collectFaceProperties(face, status);
450
451 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
452 if (expirationTime != time::steady_clock::TimePoint::max()) {
453 status.setExpirationPeriod(std::max(time::milliseconds(0),
454 time::duration_cast<time::milliseconds>(expirationTime - now)));
455 }
456
457 const face::FaceCounters& counters = face.getCounters();
458 status.setNInInterests(counters.nInInterests)
459 .setNOutInterests(counters.nOutInterests)
460 .setNInDatas(counters.nInData)
461 .setNOutDatas(counters.nOutData)
462 .setNInNacks(counters.nInNacks)
463 .setNOutNacks(counters.nOutNacks)
464 .setNInBytes(counters.nInBytes)
465 .setNOutBytes(counters.nOutBytes);
466
467 return status;
468}
469
Junxiao Shida93f1f2015-11-11 06:13:16 -0700470template<typename FaceTraits>
Junxiao Shicde37ad2015-12-24 01:02:05 -0700471void
472FaceManager::collectFaceProperties(const Face& face, FaceTraits& traits)
Junxiao Shida93f1f2015-11-11 06:13:16 -0700473{
474 traits.setFaceId(face.getId())
475 .setRemoteUri(face.getRemoteUri().toString())
476 .setLocalUri(face.getLocalUri().toString())
477 .setFaceScope(face.getScope())
478 .setFacePersistency(face.getPersistency())
479 .setLinkType(face.getLinkType());
Eric Newberry1b4ba052016-10-07 23:04:07 -0700480
481 // Set Flag bits
482 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
483 if (linkService != nullptr) {
484 auto linkServiceOptions = linkService->getOptions();
485 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
486 }
Junxiao Shida93f1f2015-11-11 06:13:16 -0700487}
488
489void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700490FaceManager::notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind)
Yanbiao Li73860e32015-08-19 16:30:16 -0700491{
492 ndn::nfd::FaceEventNotification notification;
Eric Newberry1b4ba052016-10-07 23:04:07 -0700493 notification.setKind(kind);
Junxiao Shiae04d342016-07-19 13:20:22 +0000494 collectFaceProperties(face, notification);
Yanbiao Li73860e32015-08-19 16:30:16 -0700495
Junxiao Shiae04d342016-07-19 13:20:22 +0000496 m_postNotification(notification.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700497}
498
499void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700500FaceManager::connectFaceStateChangeSignal(const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700501{
Eric Newberry1b4ba052016-10-07 23:04:07 -0700502 FaceId faceId = face.getId();
503 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
504 [this, faceId] (face::FaceState oldState, face::FaceState newState) {
505 const Face& face = *m_faceTable.get(faceId);
Yanbiao Li73860e32015-08-19 16:30:16 -0700506
Eric Newberry1b4ba052016-10-07 23:04:07 -0700507 if (newState == face::FaceState::UP) {
508 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
509 }
510 else if (newState == face::FaceState::DOWN) {
511 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
512 }
513 else if (newState == face::FaceState::CLOSED) {
514 m_faceStateChangeConn.erase(faceId);
515 }
516 });
Yanbiao Li73860e32015-08-19 16:30:16 -0700517}
518
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200519} // namespace nfd