blob: 914e3dfbbc9e45e16359bfad15fd4d6d49af9d5c [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Obaid81fb2d22014-04-07 18:10:35 -05002/**
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * 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 **/
Obaid81fb2d22014-04-07 18:10:35 -050025
Obaid81fb2d22014-04-07 18:10:35 -050026#include "face-monitor.hpp"
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070027#include "core/logger.hpp"
Obaid81fb2d22014-04-07 18:10:35 -050028
Alexander Afanasyev4a771362014-04-24 21:29:33 -070029#include <ndn-cxx/face.hpp>
Obaid81fb2d22014-04-07 18:10:35 -050030
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070031namespace nfd {
Obaid81fb2d22014-04-07 18:10:35 -050032
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070033NFD_LOG_INIT("FaceMonitor");
Obaid81fb2d22014-04-07 18:10:35 -050034
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070035FaceMonitor::FaceMonitor(ndn::Face& face)
Obaid81fb2d22014-04-07 18:10:35 -050036 : m_face(face)
37 , m_isStopped(true)
38{
39}
40
41FaceMonitor::~FaceMonitor()
42{
43}
44
45void
46FaceMonitor::removeAllSubscribers()
47{
48 m_notificationCallbacks.clear();
49 m_timeoutCallbacks.clear();
50 stopNotifications();
51}
52
53void
54FaceMonitor::stopNotifications()
55{
56 if (static_cast<bool>(m_lastInterestId))
57 m_face.removePendingInterest(m_lastInterestId);
58 m_isStopped = true;
59}
60
61void
62FaceMonitor::startNotifications()
63{
64 if (m_isStopped == false)
65 return; // Notifications cycle has been started.
66 m_isStopped = false;
67
68 Interest interest("/localhost/nfd/faces/events");
69 interest
70 .setMustBeFresh(true)
71 .setChildSelector(1)
72 .setInterestLifetime(time::seconds(60))
73 ;
74
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070075 NFD_LOG_DEBUG("startNotification: Interest Sent: " << interest);
Obaid81fb2d22014-04-07 18:10:35 -050076
77 m_lastInterestId = m_face.expressInterest(interest,
78 bind(&FaceMonitor::onNotification, this, _2),
79 bind(&FaceMonitor::onTimeout, this));
80}
81
82void
83FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback)
84{
85 addSubscriber(notificationCallback, TimeoutCallback());
86}
87
88void
89FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback,
90 const TimeoutCallback& timeoutCallback)
91{
92 if (static_cast<bool>(notificationCallback))
93 m_notificationCallbacks.push_back(notificationCallback);
94
95 if (static_cast<bool>(timeoutCallback))
96 m_timeoutCallbacks.push_back(timeoutCallback);
97}
98
99void
100FaceMonitor::onTimeout()
101{
102 if (m_isStopped)
103 return;
104
105 std::vector<TimeoutCallback>::iterator it;
106 for (it = m_timeoutCallbacks.begin();
107 it != m_timeoutCallbacks.end(); ++it) {
108 (*it)();
109 //One of the registered callbacks has cleared the vector,
110 //return now as the iterator has been invalidated and
111 //the vector is empty.
112 if (m_timeoutCallbacks.empty()) {
113 return;
114 }
115 }
116
117 Interest newInterest("/localhost/nfd/faces/events");
118 newInterest
119 .setMustBeFresh(true)
120 .setChildSelector(1)
121 .setInterestLifetime(time::seconds(60))
122 ;
123
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700124 NFD_LOG_DEBUG("In onTimeout, sending interest: " << newInterest);
Obaid81fb2d22014-04-07 18:10:35 -0500125
126 m_lastInterestId = m_face.expressInterest(newInterest,
127 bind(&FaceMonitor::onNotification, this, _2),
128 bind(&FaceMonitor::onTimeout, this));
129}
130
131void
132FaceMonitor::onNotification(const Data& data)
133{
134 if (m_isStopped)
135 return;
136
137 m_lastSequence = data.getName().get(-1).toSegment();
138 ndn::nfd::FaceEventNotification notification(data.getContent().blockFromValue());
139
140 std::vector<NotificationCallback>::iterator it;
141 for (it = m_notificationCallbacks.begin();
142 it != m_notificationCallbacks.end(); ++it) {
143 (*it)(notification);
144 if (m_notificationCallbacks.empty()) {
145 //One of the registered callbacks has cleared the vector.
146 //return back, as no one is interested in notifications anymore.
147 return;
148 }
149 }
150
151 //Setting up next notification
152 Name nextNotification("/localhost/nfd/faces/events");
153 nextNotification.appendSegment(m_lastSequence + 1);
154
155 Interest interest(nextNotification);
156 interest.setInterestLifetime(time::seconds(60));
157
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700158 NFD_LOG_DEBUG("onNotification: Interest sent: " << interest);
Obaid81fb2d22014-04-07 18:10:35 -0500159
160 m_lastInterestId = m_face.expressInterest(interest,
161 bind(&FaceMonitor::onNotification, this, _2),
162 bind(&FaceMonitor::onTimeout, this));
163}
164
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700165} // namespace nfd