rib: Integrating NRD code into NFD codebase
Change-Id: I3e548f974255f62a4680cfc6c12be3bb7a3db4d2
Refs: #1486
diff --git a/core/face-monitor.cpp b/core/face-monitor.cpp
new file mode 100644
index 0000000..658d4b9
--- /dev/null
+++ b/core/face-monitor.cpp
@@ -0,0 +1,165 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014 Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face-monitor.hpp"
+#include "core/logger.hpp"
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nfd {
+
+NFD_LOG_INIT("FaceMonitor");
+
+FaceMonitor::FaceMonitor(ndn::Face& face)
+ : m_face(face)
+ , m_isStopped(true)
+{
+}
+
+FaceMonitor::~FaceMonitor()
+{
+}
+
+void
+FaceMonitor::removeAllSubscribers()
+{
+ m_notificationCallbacks.clear();
+ m_timeoutCallbacks.clear();
+ stopNotifications();
+}
+
+void
+FaceMonitor::stopNotifications()
+{
+ if (static_cast<bool>(m_lastInterestId))
+ m_face.removePendingInterest(m_lastInterestId);
+ m_isStopped = true;
+}
+
+void
+FaceMonitor::startNotifications()
+{
+ if (m_isStopped == false)
+ return; // Notifications cycle has been started.
+ m_isStopped = false;
+
+ Interest interest("/localhost/nfd/faces/events");
+ interest
+ .setMustBeFresh(true)
+ .setChildSelector(1)
+ .setInterestLifetime(time::seconds(60))
+ ;
+
+ NFD_LOG_DEBUG("startNotification: Interest Sent: " << interest);
+
+ m_lastInterestId = m_face.expressInterest(interest,
+ bind(&FaceMonitor::onNotification, this, _2),
+ bind(&FaceMonitor::onTimeout, this));
+}
+
+void
+FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback)
+{
+ addSubscriber(notificationCallback, TimeoutCallback());
+}
+
+void
+FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback,
+ const TimeoutCallback& timeoutCallback)
+{
+ if (static_cast<bool>(notificationCallback))
+ m_notificationCallbacks.push_back(notificationCallback);
+
+ if (static_cast<bool>(timeoutCallback))
+ m_timeoutCallbacks.push_back(timeoutCallback);
+}
+
+void
+FaceMonitor::onTimeout()
+{
+ if (m_isStopped)
+ return;
+
+ std::vector<TimeoutCallback>::iterator it;
+ for (it = m_timeoutCallbacks.begin();
+ it != m_timeoutCallbacks.end(); ++it) {
+ (*it)();
+ //One of the registered callbacks has cleared the vector,
+ //return now as the iterator has been invalidated and
+ //the vector is empty.
+ if (m_timeoutCallbacks.empty()) {
+ return;
+ }
+ }
+
+ Interest newInterest("/localhost/nfd/faces/events");
+ newInterest
+ .setMustBeFresh(true)
+ .setChildSelector(1)
+ .setInterestLifetime(time::seconds(60))
+ ;
+
+ NFD_LOG_DEBUG("In onTimeout, sending interest: " << newInterest);
+
+ m_lastInterestId = m_face.expressInterest(newInterest,
+ bind(&FaceMonitor::onNotification, this, _2),
+ bind(&FaceMonitor::onTimeout, this));
+}
+
+void
+FaceMonitor::onNotification(const Data& data)
+{
+ if (m_isStopped)
+ return;
+
+ m_lastSequence = data.getName().get(-1).toSegment();
+ ndn::nfd::FaceEventNotification notification(data.getContent().blockFromValue());
+
+ std::vector<NotificationCallback>::iterator it;
+ for (it = m_notificationCallbacks.begin();
+ it != m_notificationCallbacks.end(); ++it) {
+ (*it)(notification);
+ if (m_notificationCallbacks.empty()) {
+ //One of the registered callbacks has cleared the vector.
+ //return back, as no one is interested in notifications anymore.
+ return;
+ }
+ }
+
+ //Setting up next notification
+ Name nextNotification("/localhost/nfd/faces/events");
+ nextNotification.appendSegment(m_lastSequence + 1);
+
+ Interest interest(nextNotification);
+ interest.setInterestLifetime(time::seconds(60));
+
+ NFD_LOG_DEBUG("onNotification: Interest sent: " << interest);
+
+ m_lastInterestId = m_face.expressInterest(interest,
+ bind(&FaceMonitor::onNotification, this, _2),
+ bind(&FaceMonitor::onTimeout, this));
+}
+
+} // namespace nfd
diff --git a/core/face-monitor.hpp b/core/face-monitor.hpp
new file mode 100644
index 0000000..6ce6595
--- /dev/null
+++ b/core/face-monitor.hpp
@@ -0,0 +1,105 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014 Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_CORE_FACE_MONITOR_HPP
+#define NFD_CORE_FACE_MONITOR_HPP
+
+#include "common.hpp"
+
+#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
+
+namespace ndn {
+class Face;
+struct PendingInterestId;
+}
+
+namespace nfd {
+
+using ndn::nfd::FaceEventNotification;
+
+/**
+ * \brief Helper class to subscribe to face notification events
+ *
+ * \todo Write test cases
+ */
+class FaceMonitor : noncopyable
+{
+public:
+ typedef function<void(const ndn::nfd::FaceEventNotification&)> NotificationCallback;
+ typedef function<void()> TimeoutCallback;
+
+ typedef std::vector<NotificationCallback> NotificationCallbacks;
+ typedef std::vector<TimeoutCallback> TimeoutCallbacks;
+
+ explicit
+ FaceMonitor(ndn::Face& face);
+
+ ~FaceMonitor();
+
+ /** \brief Stops all notifications. This method doesn't remove registered callbacks.
+ */
+ void
+ stopNotifications();
+
+ /** \brief Resumes notifications for added subscribers.
+ */
+ void
+ startNotifications();
+
+ /** \brief Removes all notification subscribers.
+ */
+ void
+ removeAllSubscribers();
+
+ /** \brief Adds a notification subscriber. This method doesn't return on timeouts.
+ */
+ void
+ addSubscriber(const NotificationCallback& notificationCallback);
+
+ /** \brief Adds a notification subscriber.
+ */
+ void
+ addSubscriber(const NotificationCallback& notificationCallback,
+ const TimeoutCallback& timeoutCallback);
+
+private:
+ void
+ onTimeout();
+
+ void
+ onNotification(const Data& data);
+
+private:
+ ndn::Face& m_face;
+ uint64_t m_lastSequence;
+ bool m_isStopped;
+ NotificationCallbacks m_notificationCallbacks;
+ TimeoutCallbacks m_timeoutCallbacks;
+ const ndn::PendingInterestId* m_lastInterestId;
+};
+
+} // namespace nfd
+
+#endif // NFD_CORE_FACE_MONITOR_HPP