blob: 4d1929d4599d524897146e1044a7df797acf8fbc [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{
44 registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
45 bind(&FaceManager::createFace, this, _2, _3, _4, _5));
46
Eric Newberryb5aa7f52016-09-03 20:36:12 -070047 registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
48 bind(&FaceManager::updateFace, this, _2, _3, _4, _5));
49
Yanbiao Li73860e32015-08-19 16:30:16 -070050 registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
51 bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
52
53 registerCommandHandler<ndn::nfd::FaceEnableLocalControlCommand>("enable-local-control",
54 bind(&FaceManager::enableLocalControl, this, _2, _3, _4, _5));
55
56 registerCommandHandler<ndn::nfd::FaceDisableLocalControlCommand>("disable-local-control",
57 bind(&FaceManager::disableLocalControl, this, _2, _3, _4, _5));
58
59 registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
60 registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
61 registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
62
Junxiao Shiae04d342016-07-19 13:20:22 +000063 m_postNotification = registerNotificationStream("events");
Eric Newberry1b4ba052016-10-07 23:04:07 -070064 m_faceAddConn = m_faceTable.afterAdd.connect([this] (const Face& face) {
65 connectFaceStateChangeSignal(face);
66 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
67 });
68 m_faceRemoveConn = m_faceTable.beforeRemove.connect([this] (const Face& face) {
69 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
70 });
Yanbiao Li73860e32015-08-19 16:30:16 -070071}
72
73void
74FaceManager::setConfigFile(ConfigFile& configFile)
75{
Junxiao Shib8590312016-12-29 21:22:25 +000076 m_faceSystem.setConfigFile(configFile);
Yanbiao Li73860e32015-08-19 16:30:16 -070077}
78
79void
80FaceManager::createFace(const Name& topPrefix, const Interest& interest,
81 const ControlParameters& parameters,
82 const ndn::mgmt::CommandContinuation& done)
83{
84 FaceUri uri;
85 if (!uri.parse(parameters.getUri())) {
86 NFD_LOG_TRACE("failed to parse URI");
Eric Newberry42602412016-08-27 09:33:18 -070087 done(ControlResponse(400, "Malformed command"));
88 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070089 }
90
91 if (!uri.isCanonical()) {
92 NFD_LOG_TRACE("received non-canonical URI");
Eric Newberry42602412016-08-27 09:33:18 -070093 done(ControlResponse(400, "Non-canonical URI"));
94 return;
Yanbiao Li73860e32015-08-19 16:30:16 -070095 }
96
Junxiao Shi38b24c72017-01-05 02:59:31 +000097 ProtocolFactory* factory = m_faceSystem.getFactoryByScheme(uri.getScheme());
Junxiao Shib8590312016-12-29 21:22:25 +000098 if (factory == nullptr) {
Eric Newberry42602412016-08-27 09:33:18 -070099 NFD_LOG_TRACE("received create request for unsupported protocol");
100 done(ControlResponse(406, "Unsupported protocol"));
101 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700102 }
103
104 try {
Junxiao Shib8590312016-12-29 21:22:25 +0000105 factory->createFace(uri,
106 parameters.getFacePersistency(),
107 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
108 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
109 bind(&FaceManager::afterCreateFaceSuccess, this, parameters, _1, done),
110 bind(&FaceManager::afterCreateFaceFailure, this, _1, _2, done));
Yanbiao Li73860e32015-08-19 16:30:16 -0700111 }
112 catch (const std::runtime_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700113 NFD_LOG_ERROR("Face creation failed: " << error.what());
114 done(ControlResponse(500, "Face creation failed due to internal error"));
115 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700116 }
117 catch (const std::logic_error& error) {
Eric Newberry42602412016-08-27 09:33:18 -0700118 NFD_LOG_ERROR("Face creation failed: " << error.what());
119 done(ControlResponse(500, "Face creation failed due to internal error"));
120 return;
Yanbiao Li73860e32015-08-19 16:30:16 -0700121 }
122}
123
Eric Newberry42602412016-08-27 09:33:18 -0700124/**
125 * \todo #3232
126 * If the creation of this face would conflict with an existing face (e.g. same underlying
127 * protocol and remote address, or a NIC-associated permanent face), the command will fail
128 * with StatusCode 409.
129 */
Yanbiao Li73860e32015-08-19 16:30:16 -0700130void
Eric Newberry42602412016-08-27 09:33:18 -0700131FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
Eric Newberryf40551a2016-09-05 15:41:16 -0700132 const shared_ptr<Face>& face,
Yanbiao Li73860e32015-08-19 16:30:16 -0700133 const ndn::mgmt::CommandContinuation& done)
134{
Eric Newberryf40551a2016-09-05 15:41:16 -0700135 // TODO: Re-enable check in #3232
136 //if (face->getId() != face::INVALID_FACEID) {
137 //// Face already exists
138 //ControlParameters response;
139 //response.setFaceId(face->getId());
140 //response.setUri(face->getRemoteUri().toString());
141 //response.setFacePersistency(face->getPersistency());
142 //
143 //auto linkService = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
144 //BOOST_ASSERT(linkService != nullptr);
145 //auto options = linkService->getOptions();
146 //response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
147 //
148 // NFD_LOG_TRACE("Attempted to create duplicate face of " << face->getId());
149 // done(ControlResponse(409, "Face with remote URI already exists").setBody(response.wireEncode()));
150 //}
151 //else {
152 // If scope non-local and flags set to enable local fields, request shouldn't
153 // have made it this far
154 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
155 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
156 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
157 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
158
159 m_faceTable.add(face);
160
Eric Newberry42602412016-08-27 09:33:18 -0700161 ControlParameters response;
Eric Newberryf40551a2016-09-05 15:41:16 -0700162 response.setFaceId(face->getId());
163 response.setFacePersistency(face->getPersistency());
164 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
165 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
166 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
167 false);
Eric Newberry42602412016-08-27 09:33:18 -0700168
169 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
Eric Newberryf40551a2016-09-05 15:41:16 -0700170 //}
Eric Newberry42602412016-08-27 09:33:18 -0700171}
172
173void
174FaceManager::afterCreateFaceFailure(uint32_t status,
175 const std::string& reason,
176 const ndn::mgmt::CommandContinuation& done)
177{
178 NFD_LOG_DEBUG("Face creation failed: " << reason);
179
180 done(ControlResponse(status, reason));
Yanbiao Li73860e32015-08-19 16:30:16 -0700181}
182
183void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700184FaceManager::updateFace(const Name& topPrefix, const Interest& interest,
185 const ControlParameters& parameters,
186 const ndn::mgmt::CommandContinuation& done)
187{
188 FaceId faceId = parameters.getFaceId();
189 if (faceId == 0) {
190 // Self-updating
191 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
192 if (incomingFaceIdTag == nullptr) {
193 NFD_LOG_TRACE("unable to determine face for self-update");
194 done(ControlResponse(404, "No FaceId specified and IncomingFaceId not available"));
195 return;
196 }
197 faceId = *incomingFaceIdTag;
198 }
199
200 Face* face = m_faceTable.get(faceId);
201
202 if (face == nullptr) {
203 NFD_LOG_TRACE("invalid face specified");
204 done(ControlResponse(404, "Specified face does not exist"));
205 return;
206 }
207
208 // Verify validity of requested changes
209 ControlParameters response;
210 bool areParamsValid = true;
211
212 if (parameters.hasFacePersistency()) {
213 // TODO #3232: Add FacePersistency updating
214 NFD_LOG_TRACE("received unsupported face persistency change");
215 areParamsValid = false;
216 response.setFacePersistency(parameters.getFacePersistency());
217 }
218
219 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
220 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
221 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
222 NFD_LOG_TRACE("received request to enable local fields on non-local face");
223 areParamsValid = false;
224 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
225 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
226 }
227
228 if (!areParamsValid) {
229 done(ControlResponse(409, "Invalid properties specified").setBody(response.wireEncode()));
230 return;
231 }
232
233 // All specified properties are valid, so make changes
234
235 // TODO #3232: Add FacePersistency updating
236
237 setLinkServiceOptions(*face, parameters, response);
238
Eric Newberryf40551a2016-09-05 15:41:16 -0700239 // Set ControlResponse fields
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700240 response.setFaceId(faceId);
241 response.setFacePersistency(face->getPersistency());
Eric Newberryf40551a2016-09-05 15:41:16 -0700242 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
243 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
244 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
245 false);
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700246
247 done(ControlResponse(200, "OK").setBody(response.wireEncode()));
248}
249
250void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700251FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
252 const ControlParameters& parameters,
253 const ndn::mgmt::CommandContinuation& done)
254{
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000255 Face* face = m_faceTable.get(parameters.getFaceId());
256 if (face != nullptr) {
257 face->close();
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700258 }
259
260 done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
261}
262
263void
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700264FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
265 const ControlParameters& parameters,
266 const ndn::mgmt::CommandContinuation& done)
267{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700268 Face* face = findFaceForLocalControl(interest, parameters, done);
269 if (!face) {
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700270 return;
271 }
272
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700273 // enable-local-control will enable all local fields in GenericLinkService
Junxiao Shicde37ad2015-12-24 01:02:05 -0700274 auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700275 if (service == nullptr) {
276 return done(ControlResponse(503, "LinkService type not supported"));
277 }
278
279 face::GenericLinkService::Options options = service->getOptions();
280 options.allowLocalFields = true;
281 service->setOptions(options);
282
283 return done(ControlResponse(200, "OK: enable all local fields on GenericLinkService")
284 .setBody(parameters.wireEncode()));
285}
286
287void
288FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
289 const ControlParameters& parameters,
290 const ndn::mgmt::CommandContinuation& done)
291{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700292 Face* face = findFaceForLocalControl(interest, parameters, done);
293 if (!face) {
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700294 return;
295 }
296
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700297 // disable-local-control will disable all local fields in GenericLinkService
Junxiao Shicde37ad2015-12-24 01:02:05 -0700298 auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
Junxiao Shi40cb61c2015-09-23 18:36:45 -0700299 if (service == nullptr) {
300 return done(ControlResponse(503, "LinkService type not supported"));
301 }
302
303 face::GenericLinkService::Options options = service->getOptions();
304 options.allowLocalFields = false;
305 service->setOptions(options);
306
307 return done(ControlResponse(200, "OK: disable all local fields on GenericLinkService")
308 .setBody(parameters.wireEncode()));
309}
310
Junxiao Shicde37ad2015-12-24 01:02:05 -0700311Face*
312FaceManager::findFaceForLocalControl(const Interest& request,
313 const ControlParameters& parameters,
314 const ndn::mgmt::CommandContinuation& done)
Yanbiao Li73860e32015-08-19 16:30:16 -0700315{
Junxiao Shi0de23a22015-12-03 20:07:02 +0000316 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
317 // NDNLPv2 says "application MUST be prepared to receive a packet without IncomingFaceId field",
318 // but it's fine to assert IncomingFaceId is available, because InternalFace lives inside NFD
319 // and is initialized synchronously with IncomingFaceId field enabled.
320 BOOST_ASSERT(incomingFaceIdTag != nullptr);
321
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000322 Face* face = m_faceTable.get(*incomingFaceIdTag);
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200323 if (face == nullptr) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000324 NFD_LOG_DEBUG("FaceId " << *incomingFaceIdTag << " not found");
Yanbiao Li73860e32015-08-19 16:30:16 -0700325 done(ControlResponse(410, "Face not found"));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700326 return nullptr;
Yanbiao Li73860e32015-08-19 16:30:16 -0700327 }
328
Junxiao Shicde37ad2015-12-24 01:02:05 -0700329 if (face->getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL) {
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200330 NFD_LOG_DEBUG("Cannot enable local control on non-local FaceId " << face->getId());
Yanbiao Li73860e32015-08-19 16:30:16 -0700331 done(ControlResponse(412, "Face is non-local"));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700332 return nullptr;
Yanbiao Li73860e32015-08-19 16:30:16 -0700333 }
334
Junxiao Shi5b43f9a2016-07-19 13:15:56 +0000335 return face;
Yanbiao Li73860e32015-08-19 16:30:16 -0700336}
337
338void
Eric Newberryb5aa7f52016-09-03 20:36:12 -0700339FaceManager::setLinkServiceOptions(Face& face,
340 const ControlParameters& parameters,
341 ControlParameters& response)
342{
343 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
344 BOOST_ASSERT(linkService != nullptr);
345
346 auto options = linkService->getOptions();
347 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
348 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
349 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
350 }
351 linkService->setOptions(options);
352
353 // Set Flags for ControlResponse
354 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
355}
356
357void
Yanbiao Li73860e32015-08-19 16:30:16 -0700358FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
359 ndn::mgmt::StatusDatasetContext& context)
360{
Eric Newberryc64d30a2015-12-26 11:07:27 -0700361 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000362 for (const Face& face : m_faceTable) {
363 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700364 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700365 }
366 context.end();
367}
368
369void
370FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
371 ndn::mgmt::StatusDatasetContext& context)
372{
Junxiao Shib8590312016-12-29 21:22:25 +0000373 std::set<const ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
374 for (const ProtocolFactory* factory : factories) {
375 for (const auto& channel : factory->getChannels()) {
376 ndn::nfd::ChannelStatus entry;
377 entry.setLocalUri(channel->getUri().toString());
378 context.append(entry.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700379 }
380 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700381 context.end();
382}
383
384void
385FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
386 ndn::mgmt::StatusDatasetContext& context)
387{
388 ndn::nfd::FaceQueryFilter faceFilter;
389 const Name& query = interest.getName();
390 try {
391 faceFilter.wireDecode(query[-1].blockFromValue());
392 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200393 catch (const tlv::Error& e) {
394 NFD_LOG_DEBUG("Malformed query filter: " << e.what());
395 return context.reject(ControlResponse(400, "Malformed filter"));
Yanbiao Li73860e32015-08-19 16:30:16 -0700396 }
397
Eric Newberryc64d30a2015-12-26 11:07:27 -0700398 auto now = time::steady_clock::now();
Junxiao Shib84e6742016-07-19 13:16:22 +0000399 for (const Face& face : m_faceTable) {
400 if (!matchFilter(faceFilter, face)) {
Junxiao Shida93f1f2015-11-11 06:13:16 -0700401 continue;
Yanbiao Li73860e32015-08-19 16:30:16 -0700402 }
Junxiao Shib84e6742016-07-19 13:16:22 +0000403 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700404 context.append(status.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700405 }
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200406
Yanbiao Li73860e32015-08-19 16:30:16 -0700407 context.end();
408}
409
410bool
Junxiao Shib84e6742016-07-19 13:16:22 +0000411FaceManager::matchFilter(const ndn::nfd::FaceQueryFilter& filter, const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700412{
413 if (filter.hasFaceId() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000414 filter.getFaceId() != static_cast<uint64_t>(face.getId())) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700415 return false;
416 }
417
418 if (filter.hasUriScheme() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000419 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
420 filter.getUriScheme() != face.getLocalUri().getScheme()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700421 return false;
422 }
423
424 if (filter.hasRemoteUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000425 filter.getRemoteUri() != face.getRemoteUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700426 return false;
427 }
428
429 if (filter.hasLocalUri() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000430 filter.getLocalUri() != face.getLocalUri().toString()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700431 return false;
432 }
433
434 if (filter.hasFaceScope() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000435 filter.getFaceScope() != face.getScope()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700436 return false;
437 }
438
439 if (filter.hasFacePersistency() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000440 filter.getFacePersistency() != face.getPersistency()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700441 return false;
442 }
443
444 if (filter.hasLinkType() &&
Junxiao Shib84e6742016-07-19 13:16:22 +0000445 filter.getLinkType() != face.getLinkType()) {
Yanbiao Li73860e32015-08-19 16:30:16 -0700446 return false;
447 }
448
449 return true;
450}
451
Eric Newberryc64d30a2015-12-26 11:07:27 -0700452ndn::nfd::FaceStatus
453FaceManager::collectFaceStatus(const Face& face, const time::steady_clock::TimePoint& now)
454{
455 ndn::nfd::FaceStatus status;
456
457 collectFaceProperties(face, status);
458
459 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
460 if (expirationTime != time::steady_clock::TimePoint::max()) {
461 status.setExpirationPeriod(std::max(time::milliseconds(0),
462 time::duration_cast<time::milliseconds>(expirationTime - now)));
463 }
464
465 const face::FaceCounters& counters = face.getCounters();
466 status.setNInInterests(counters.nInInterests)
467 .setNOutInterests(counters.nOutInterests)
468 .setNInDatas(counters.nInData)
469 .setNOutDatas(counters.nOutData)
470 .setNInNacks(counters.nInNacks)
471 .setNOutNacks(counters.nOutNacks)
472 .setNInBytes(counters.nInBytes)
473 .setNOutBytes(counters.nOutBytes);
474
475 return status;
476}
477
Junxiao Shida93f1f2015-11-11 06:13:16 -0700478template<typename FaceTraits>
Junxiao Shicde37ad2015-12-24 01:02:05 -0700479void
480FaceManager::collectFaceProperties(const Face& face, FaceTraits& traits)
Junxiao Shida93f1f2015-11-11 06:13:16 -0700481{
482 traits.setFaceId(face.getId())
483 .setRemoteUri(face.getRemoteUri().toString())
484 .setLocalUri(face.getLocalUri().toString())
485 .setFaceScope(face.getScope())
486 .setFacePersistency(face.getPersistency())
487 .setLinkType(face.getLinkType());
Eric Newberry1b4ba052016-10-07 23:04:07 -0700488
489 // Set Flag bits
490 auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
491 if (linkService != nullptr) {
492 auto linkServiceOptions = linkService->getOptions();
493 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
494 }
Junxiao Shida93f1f2015-11-11 06:13:16 -0700495}
496
497void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700498FaceManager::notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind)
Yanbiao Li73860e32015-08-19 16:30:16 -0700499{
500 ndn::nfd::FaceEventNotification notification;
Eric Newberry1b4ba052016-10-07 23:04:07 -0700501 notification.setKind(kind);
Junxiao Shiae04d342016-07-19 13:20:22 +0000502 collectFaceProperties(face, notification);
Yanbiao Li73860e32015-08-19 16:30:16 -0700503
Junxiao Shiae04d342016-07-19 13:20:22 +0000504 m_postNotification(notification.wireEncode());
Yanbiao Li73860e32015-08-19 16:30:16 -0700505}
506
507void
Eric Newberry1b4ba052016-10-07 23:04:07 -0700508FaceManager::connectFaceStateChangeSignal(const Face& face)
Yanbiao Li73860e32015-08-19 16:30:16 -0700509{
Eric Newberry1b4ba052016-10-07 23:04:07 -0700510 FaceId faceId = face.getId();
511 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
512 [this, faceId] (face::FaceState oldState, face::FaceState newState) {
513 const Face& face = *m_faceTable.get(faceId);
Yanbiao Li73860e32015-08-19 16:30:16 -0700514
Eric Newberry1b4ba052016-10-07 23:04:07 -0700515 if (newState == face::FaceState::UP) {
516 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
517 }
518 else if (newState == face::FaceState::DOWN) {
519 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
520 }
521 else if (newState == face::FaceState::CLOSED) {
522 m_faceStateChangeConn.erase(faceId);
523 }
524 });
Yanbiao Li73860e32015-08-19 16:30:16 -0700525}
526
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200527} // namespace nfd