blob: e8a79ebfc8e54c2177f12b61631852191a8604c2 [file] [log] [blame]
Yanbiao Li73860e32015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yanbiao Lidf846e52016-01-30 21:53:47 -08003 * Copyright (c) 2014-2016, 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 Shi9ddf1b52016-08-22 03:58:55 +000038FaceManager::FaceManager(FaceTable& faceTable, Dispatcher& dispatcher, CommandAuthenticator& authenticator)
39 : NfdManagerBase(dispatcher, authenticator, "faces")
Junxiao Shib8590312016-12-29 21:22:25 +000040 , m_faceSystem(faceTable)
Yanbiao Li73860e32015-08-19 16:30:16 -070041 , m_faceTable(faceTable)
42{
43 registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
44 bind(&FaceManager::createFace, this, _2, _3, _4, _5));
45
Eric Newberryb5aa7f52016-09-03 20:36:12 -070046 registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
47 bind(&FaceManager::updateFace, this, _2, _3, _4, _5));
48
Yanbiao Li73860e32015-08-19 16:30:16 -070049 registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
50 bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
51
52 registerCommandHandler<ndn::nfd::FaceEnableLocalControlCommand>("enable-local-control",
53 bind(&FaceManager::enableLocalControl, this, _2, _3, _4, _5));
54
55 registerCommandHandler<ndn::nfd::FaceDisableLocalControlCommand>("disable-local-control",
56 bind(&FaceManager::disableLocalControl, this, _2, _3, _4, _5));
57
58 registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
59 registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
60 registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
61
Junxiao Shiae04d342016-07-19 13:20:22 +000062 m_postNotification = registerNotificationStream("events");
Eric Newberry1b4ba052016-10-07 23:04:07 -070063 m_faceAddConn = m_faceTable.afterAdd.connect([this] (const Face& face) {
64 connectFaceStateChangeSignal(face);
65 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
66 });
67 m_faceRemoveConn = m_faceTable.beforeRemove.connect([this] (const Face& face) {
68 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
69 });
Yanbiao Li73860e32015-08-19 16:30:16 -070070}
71
72void
73FaceManager::setConfigFile(ConfigFile& configFile)
74{
Junxiao Shib8590312016-12-29 21:22:25 +000075 m_faceSystem.setConfigFile(configFile);
Yanbiao Li73860e32015-08-19 16:30:16 -070076}
77
78void
79FaceManager::createFace(const Name& topPrefix, const Interest& interest,
80 const ControlParameters& parameters,
81 const ndn::mgmt::CommandContinuation& done)
82{
83 FaceUri uri;
84 if (!uri.parse(parameters.getUri())) {
85 NFD_LOG_TRACE("failed to parse URI");
Eric Newberry42602412016-08-27 09:33:18 -070086 done(ControlResponse(400, "Malformed command"));
87 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070088 }
89
90 if (!uri.isCanonical()) {
91 NFD_LOG_TRACE("received non-canonical URI");
Eric Newberry42602412016-08-27 09:33:18 -070092 done(ControlResponse(400, "Non-canonical URI"));
93 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070094 }
95
Junxiao Shib8590312016-12-29 21:22:25 +000096 ProtocolFactory* factory = m_faceSystem.getProtocolFactory(uri.getScheme());
97 if (factory == nullptr) {
Eric Newberry42602412016-08-27 09:33:18 -070098 NFD_LOG_TRACE("received create request for unsupported protocol");
99 done(ControlResponse(406, "Unsupported protocol"));
100 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700101 }
102
103 try {
Junxiao Shib8590312016-12-29 21:22:25 +0000104 factory->createFace(uri,
105 parameters.getFacePersistency(),
106 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
107 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
108 bind(&FaceManager::afterCreateFaceSuccess, this, parameters, _1, done),
109 bind(&FaceManager::afterCreateFaceFailure, this, _1, _2, done));
Yanbiao Li73860e32015-08-19 16:30:16 -0700110 }
111 catch (const std::runtime_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700112 NFD_LOG_ERROR("Face creation failed: " << error.what());
113 done(ControlResponse(500, "Face creation failed due to internal error"));
114 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700115 }
116 catch (const std::logic_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700117 NFD_LOG_ERROR("Face creation failed: " << error.what());
118 done(ControlResponse(500, "Face creation failed due to internal error"));
119 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700120 }
121}
122
Eric Newberry42602412016-08-27 09:33:18 -0700123/**
124 * \todo #3232
125 * If the creation of this face would conflict with an existing face (e.g. same underlying
126 * protocol and remote address, or a NIC-associated permanent face), the command will fail
127 * with StatusCode 409.
128 */
Yanbiao Li73860e32015-08-19 16:30:16 -0700129void
Eric Newberry42602412016-08-27 09:33:18 -0700130FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
Eric Newberryf40551a2016-09-05 15:41:16 -0700131 const shared_ptr<Face>& face,
Yanbiao Li73860e32015-08-19 16:30:16 -0700132 const ndn::mgmt::CommandContinuation& done)
133{
Eric Newberryf40551a2016-09-05 15:41:16 -0700134 // TODO: Re-enable check in #3232
135 //if (face->getId() != face::INVALID_FACEID) {
136 //// Face already exists
137 //ControlParameters response;
138 //response.setFaceId(face->getId());
139 //response.setUri(face->getRemoteUri().toString());
140 //response.setFacePersistency(face->getPersistency());
141 //
142 //auto linkService = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
143 //BOOST_ASSERT(linkService != nullptr);
144 //auto options = linkService->getOptions();
145 //response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
146 //
147 // NFD_LOG_TRACE("Attempted to create duplicate face of " << face->getId());
148 // done(ControlResponse(409, "Face with remote URI already exists").setBody(response.wireEncode()));
149 //}
150 //else {
151 // If scope non-local and flags set to enable local fields, request shouldn't
152 // have made it this far
153 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
154 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
155 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
156 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
157
158 m_faceTable.add(face);
159
Eric Newberry42602412016-08-27 09:33:18 -0700160 ControlParameters response;
Eric Newberryf40551a2016-09-05 15:41:16 -0700161 response.setFaceId(face->getId());
162 response.setFacePersistency(face->getPersistency());
163 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
164 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
165 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
166 false);
Eric Newberry42602412016-08-27 09:33:18 -0700167
168 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
Eric Newberryf40551a2016-09-05 15:41:16 -0700169 //}
Eric Newberry42602412016-08-27 09:33:18 -0700170}
171
172void
173FaceManager::afterCreateFaceFailure(uint32_t status,
174 const std::string& reason,
175 const ndn::mgmt::CommandContinuation& done)
176{
177 NFD_LOG_DEBUG("Face creation failed: " << reason);
178
179 done(ControlResponse(status, reason));
Yanbiao Li73860e32015-08-19 16:30:16 -0700180}
181
182void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700183FaceManager::updateFace(const Name& topPrefix, const Interest& interest,
184 const ControlParameters& parameters,
185 const ndn::mgmt::CommandContinuation& done)
186{
187 FaceId faceId = parameters.getFaceId();
188 if (faceId == 0) {
189 // Self-updating
190 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
191 if (incomingFaceIdTag == nullptr) {
192 NFD_LOG_TRACE("unable to determine face for self-update");
193 done(ControlResponse(404, "No FaceId specified and IncomingFaceId not available"));
194 return;
195 }
196 faceId = *incomingFaceIdTag;
197 }
198
199 Face* face = m_faceTable.get(faceId);
200
201 if (face == nullptr) {
202 NFD_LOG_TRACE("invalid face specified");
203 done(ControlResponse(404, "Specified face does not exist"));
204 return;
205 }
206
207 // Verify validity of requested changes
208 ControlParameters response;
209 bool areParamsValid = true;
210
211 if (parameters.hasFacePersistency()) {
212 // TODO #3232: Add FacePersistency updating
213 NFD_LOG_TRACE("received unsupported face persistency change");
214 areParamsValid = false;
215 response.setFacePersistency(parameters.getFacePersistency());
216 }
217
218 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
219 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
220 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
221 NFD_LOG_TRACE("received request to enable local fields on non-local face");
222 areParamsValid = false;
223 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
224 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
225 }
226
227 if (!areParamsValid) {
228 done(ControlResponse(409, "Invalid properties specified").setBody(response.wireEncode()));
229 return;
230 }
231
232 // All specified properties are valid, so make changes
233
234 // TODO #3232: Add FacePersistency updating
235
236 setLinkServiceOptions(*face, parameters, response);
237
Eric Newberryf40551a2016-09-05 15:41:16 -0700238 // Set ControlResponse fields
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700239 response.setFaceId(faceId);
240 response.setFacePersistency(face->getPersistency());
Eric Newberryf40551a2016-09-05 15:41:16 -0700241 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
242 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
243 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
244 false);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700245
246 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
247}
248
249void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700250FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
251 const ControlParameters& parameters,
252 const ndn::mgmt::CommandContinuation& done)
253{
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000254 Face* face = m_faceTable.get(parameters.getFaceId());
255 if (face != nullptr) {
256 face->close();
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700257 }
258
259 done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
260}
261
262void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700263FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
264 const ControlParameters& parameters,
265 const ndn::mgmt::CommandContinuation& done)
266{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700267 Face* face = findFaceForLocalControl(interest, parameters, done);
268 if (!face) {
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700269 return;
270 }
271
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700272 // enable-local-control will enable all local fields in GenericLinkService
Junxiao Shicde37ad2015-12-24 01:02:05 -0700273 auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700274 if (service == nullptr) {
275 return done(ControlResponse(503, "LinkService type not supported"));
276 }
277
278 face::GenericLinkService::Options options = service->getOptions();
279 options.allowLocalFields = true;
280 service->setOptions(options);
281
282 return done(ControlResponse(200, "OK: enable all local fields on GenericLinkService")
283 .setBody(parameters.wireEncode()));
284}
285
286void
287FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
288 const ControlParameters& parameters,
289 const ndn::mgmt::CommandContinuation& done)
290{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700291 Face* face = findFaceForLocalControl(interest, parameters, done);
292 if (!face) {
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700293 return;
294 }
295
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700296 // disable-local-control will disable all local fields in GenericLinkService
Junxiao Shicde37ad2015-12-24 01:02:05 -0700297 auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700298 if (service == nullptr) {
299 return done(ControlResponse(503, "LinkService type not supported"));
300 }
301
302 face::GenericLinkService::Options options = service->getOptions();
303 options.allowLocalFields = false;
304 service->setOptions(options);
305
306 return done(ControlResponse(200, "OK: disable all local fields on GenericLinkService")
307 .setBody(parameters.wireEncode()));
308}
309
Junxiao Shicde37ad2015-12-24 01:02:05 -0700310Face*
311FaceManager::findFaceForLocalControl(const Interest& request,
312 const ControlParameters& parameters,
313 const ndn::mgmt::CommandContinuation& done)
Yanbiao Li73860e32015-08-19 16:30:16 -0700314{
Junxiao Shi0de23a22015-12-03 20:07:02 +0000315 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
316 // NDNLPv2 says "application MUST be prepared to receive a packet without IncomingFaceId field",
317 // but it's fine to assert IncomingFaceId is available, because InternalFace lives inside NFD
318 // and is initialized synchronously with IncomingFaceId field enabled.
319 BOOST_ASSERT(incomingFaceIdTag != nullptr);
320
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000321 Face* face = m_faceTable.get(*incomingFaceIdTag);
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200322 if (face == nullptr) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000323 NFD_LOG_DEBUG("FaceId " << *incomingFaceIdTag << " not found");
Yanbiao Li73860e32015-08-19 16:30:16 -0700324 done(ControlResponse(410, "Face not found"));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700325 return nullptr;
Yanbiao Li73860e32015-08-19 16:30:16 -0700326 }
327
Junxiao Shicde37ad2015-12-24 01:02:05 -0700328 if (face->getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL) {
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200329 NFD_LOG_DEBUG("Cannot enable local control on non-local FaceId " << face->getId());
Yanbiao Li73860e32015-08-19 16:30:16 -0700330 done(ControlResponse(412, "Face is non-local"));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700331 return nullptr;
Yanbiao Li73860e32015-08-19 16:30:16 -0700332 }
333
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000334 return face;
Yanbiao Li73860e32015-08-19 16:30:16 -0700335}
336
337void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700338FaceManager::setLinkServiceOptions(Face& face,
339 const ControlParameters& parameters,
340 ControlParameters& response)
341{
342 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
343 BOOST_ASSERT(linkService != nullptr);
344
345 auto options = linkService->getOptions();
346 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
347 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
348 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
349 }
350 linkService->setOptions(options);
351
352 // Set Flags for ControlResponse
353 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
354}
355
356void
Yanbiao Li73860e32015-08-19 16:30:16 -0700357FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
358 ndn::mgmt::StatusDatasetContext& context)
359{
Eric Newberryc64d30a2015-12-26 11:07:27 -0700360 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000361 for (const Face& face : m_faceTable) {
362 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700363 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700364 }
365 context.end();
366}
367
368void
369FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
370 ndn::mgmt::StatusDatasetContext& context)
371{
Junxiao Shib8590312016-12-29 21:22:25 +0000372 std::set<const ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
373 for (const ProtocolFactory* factory : factories) {
374 for (const auto& channel : factory->getChannels()) {
375 ndn::nfd::ChannelStatus entry;
376 entry.setLocalUri(channel->getUri().toString());
377 context.append(entry.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700378 }
379 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700380 context.end();
381}
382
383void
384FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
385 ndn::mgmt::StatusDatasetContext& context)
386{
387 ndn::nfd::FaceQueryFilter faceFilter;
388 const Name& query = interest.getName();
389 try {
390 faceFilter.wireDecode(query[-1].blockFromValue());
391 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200392 catch (const tlv::Error& e) {
393 NFD_LOG_DEBUG("Malformed query filter: " << e.what());
394 return context.reject(ControlResponse(400, "Malformed filter"));
Yanbiao Li73860e32015-08-19 16:30:16 -0700395 }
396
Eric Newberryc64d30a2015-12-26 11:07:27 -0700397 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000398 for (const Face& face : m_faceTable) {
399 if (!matchFilter(faceFilter, face)) {
Junxiao Shida93f1f2015-11-11 06:13:16 -0700400 continue;
Yanbiao Li73860e32015-08-19 16:30:16 -0700401 }
Junxiao Shib84e6742016-07-19 13:16:22 +0000402 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700403 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700404 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200405
Yanbiao Li73860e32015-08-19 16:30:16 -0700406 context.end();
407}
408
409bool
Junxiao Shib84e6742016-07-19 13:16:22 +0000410FaceManager::matchFilter(const ndn::nfd::FaceQueryFilter& filter, const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700411{
412 if (filter.hasFaceId() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000413 filter.getFaceId() != static_cast<uint64_t>(face.getId())) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700414 return false;
415 }
416
417 if (filter.hasUriScheme() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000418 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
419 filter.getUriScheme() != face.getLocalUri().getScheme()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700420 return false;
421 }
422
423 if (filter.hasRemoteUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000424 filter.getRemoteUri() != face.getRemoteUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700425 return false;
426 }
427
428 if (filter.hasLocalUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000429 filter.getLocalUri() != face.getLocalUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700430 return false;
431 }
432
433 if (filter.hasFaceScope() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000434 filter.getFaceScope() != face.getScope()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700435 return false;
436 }
437
438 if (filter.hasFacePersistency() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000439 filter.getFacePersistency() != face.getPersistency()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700440 return false;
441 }
442
443 if (filter.hasLinkType() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000444 filter.getLinkType() != face.getLinkType()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700445 return false;
446 }
447
448 return true;
449}
450
Eric Newberryc64d30a2015-12-26 11:07:27 -0700451ndn::nfd::FaceStatus
452FaceManager::collectFaceStatus(const Face& face, const time::steady_clock::TimePoint& now)
453{
454 ndn::nfd::FaceStatus status;
455
456 collectFaceProperties(face, status);
457
458 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
459 if (expirationTime != time::steady_clock::TimePoint::max()) {
460 status.setExpirationPeriod(std::max(time::milliseconds(0),
461 time::duration_cast<time::milliseconds>(expirationTime - now)));
462 }
463
464 const face::FaceCounters& counters = face.getCounters();
465 status.setNInInterests(counters.nInInterests)
466 .setNOutInterests(counters.nOutInterests)
467 .setNInDatas(counters.nInData)
468 .setNOutDatas(counters.nOutData)
469 .setNInNacks(counters.nInNacks)
470 .setNOutNacks(counters.nOutNacks)
471 .setNInBytes(counters.nInBytes)
472 .setNOutBytes(counters.nOutBytes);
473
474 return status;
475}
476
Junxiao Shida93f1f2015-11-11 06:13:16 -0700477template<typename FaceTraits>
Junxiao Shicde37ad2015-12-24 01:02:05 -0700478void
479FaceManager::collectFaceProperties(const Face& face, FaceTraits& traits)
Junxiao Shida93f1f2015-11-11 06:13:16 -0700480{
481 traits.setFaceId(face.getId())
482 .setRemoteUri(face.getRemoteUri().toString())
483 .setLocalUri(face.getLocalUri().toString())
484 .setFaceScope(face.getScope())
485 .setFacePersistency(face.getPersistency())
486 .setLinkType(face.getLinkType());
Eric Newberry1b4ba052016-10-07 23:04:07 -0700487
488 // Set Flag bits
489 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
490 if (linkService != nullptr) {
491 auto linkServiceOptions = linkService->getOptions();
492 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
493 }
Junxiao Shida93f1f2015-11-11 06:13:16 -0700494}
495
496void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700497FaceManager::notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind)
Yanbiao Li73860e32015-08-19 16:30:16 -0700498{
499 ndn::nfd::FaceEventNotification notification;
Eric Newberry1b4ba052016-10-07 23:04:07 -0700500 notification.setKind(kind);
Junxiao Shiae04d342016-07-19 13:20:22 +0000501 collectFaceProperties(face, notification);
Yanbiao Li73860e32015-08-19 16:30:16 -0700502
Junxiao Shiae04d342016-07-19 13:20:22 +0000503 m_postNotification(notification.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700504}
505
506void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700507FaceManager::connectFaceStateChangeSignal(const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700508{
Eric Newberry1b4ba052016-10-07 23:04:07 -0700509 FaceId faceId = face.getId();
510 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
511 [this, faceId] (face::FaceState oldState, face::FaceState newState) {
512 const Face& face = *m_faceTable.get(faceId);
Yanbiao Li73860e32015-08-19 16:30:16 -0700513
Eric Newberry1b4ba052016-10-07 23:04:07 -0700514 if (newState == face::FaceState::UP) {
515 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
516 }
517 else if (newState == face::FaceState::DOWN) {
518 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
519 }
520 else if (newState == face::FaceState::CLOSED) {
521 m_faceStateChangeConn.erase(faceId);
522 }
523 });
Yanbiao Li73860e32015-08-19 16:30:16 -0700524}
525
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200526} // namespace nfd