blob: f4345238721b67e36f818887a66d26e766d8bb0d [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
* Copyright (C) 2014 Regents of the University of California.
* See COPYING for copyright and distribution information.
*/
#include "common.hpp"
#include "face-monitor.hpp"
#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
namespace ndn {
using namespace nfd;
FaceMonitor::FaceMonitor(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))
;
//todo: add logging support.
std::cout << "startNotification: Interest Sent: " << interest << std::endl;
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))
;
//todo: add logging support.
std::cout << "In onTimeout, sending interest: " << newInterest << std::endl;
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));
//todo: add logging support.
std::cout << "onNotification: Interest sent: " << interest << std::endl;
m_lastInterestId = m_face.expressInterest(interest,
bind(&FaceMonitor::onNotification, this, _2),
bind(&FaceMonitor::onTimeout, this));
}
}//namespace ndn