blob: f4143a95b529be6f72b0b50d5df0139f7b76a7e3 [file] [log] [blame]
Obaid81fb2d22014-04-07 18:10:35 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2014 Regents of the University of California.
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "common.hpp"
8#include "face-monitor.hpp"
9#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
10
11
12namespace ndn {
13
14using namespace nfd;
15
16FaceMonitor::FaceMonitor(Face& face)
17 : m_face(face)
18 , m_isStopped(true)
19{
20}
21
22FaceMonitor::~FaceMonitor()
23{
24}
25
26void
27FaceMonitor::removeAllSubscribers()
28{
29 m_notificationCallbacks.clear();
30 m_timeoutCallbacks.clear();
31 stopNotifications();
32}
33
34void
35FaceMonitor::stopNotifications()
36{
37 if (static_cast<bool>(m_lastInterestId))
38 m_face.removePendingInterest(m_lastInterestId);
39 m_isStopped = true;
40}
41
42void
43FaceMonitor::startNotifications()
44{
45 if (m_isStopped == false)
46 return; // Notifications cycle has been started.
47 m_isStopped = false;
48
49 Interest interest("/localhost/nfd/faces/events");
50 interest
51 .setMustBeFresh(true)
52 .setChildSelector(1)
53 .setInterestLifetime(time::seconds(60))
54 ;
55
56 //todo: add logging support.
57 std::cout << "startNotification: Interest Sent: " << interest << std::endl;
58
59 m_lastInterestId = m_face.expressInterest(interest,
60 bind(&FaceMonitor::onNotification, this, _2),
61 bind(&FaceMonitor::onTimeout, this));
62}
63
64void
65FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback)
66{
67 addSubscriber(notificationCallback, TimeoutCallback());
68}
69
70void
71FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback,
72 const TimeoutCallback& timeoutCallback)
73{
74 if (static_cast<bool>(notificationCallback))
75 m_notificationCallbacks.push_back(notificationCallback);
76
77 if (static_cast<bool>(timeoutCallback))
78 m_timeoutCallbacks.push_back(timeoutCallback);
79}
80
81void
82FaceMonitor::onTimeout()
83{
84 if (m_isStopped)
85 return;
86
87 std::vector<TimeoutCallback>::iterator it;
88 for (it = m_timeoutCallbacks.begin();
89 it != m_timeoutCallbacks.end(); ++it) {
90 (*it)();
91 //One of the registered callbacks has cleared the vector,
92 //return now as the iterator has been invalidated and
93 //the vector is empty.
94 if (m_timeoutCallbacks.empty()) {
95 return;
96 }
97 }
98
99 Interest newInterest("/localhost/nfd/faces/events");
100 newInterest
101 .setMustBeFresh(true)
102 .setChildSelector(1)
103 .setInterestLifetime(time::seconds(60))
104 ;
105
106 //todo: add logging support.
107 std::cout << "In onTimeout, sending interest: " << newInterest << std::endl;
108
109 m_lastInterestId = m_face.expressInterest(newInterest,
110 bind(&FaceMonitor::onNotification, this, _2),
111 bind(&FaceMonitor::onTimeout, this));
112}
113
114void
115FaceMonitor::onNotification(const Data& data)
116{
117 if (m_isStopped)
118 return;
119
120 m_lastSequence = data.getName().get(-1).toSegment();
121 ndn::nfd::FaceEventNotification notification(data.getContent().blockFromValue());
122
123 std::vector<NotificationCallback>::iterator it;
124 for (it = m_notificationCallbacks.begin();
125 it != m_notificationCallbacks.end(); ++it) {
126 (*it)(notification);
127 if (m_notificationCallbacks.empty()) {
128 //One of the registered callbacks has cleared the vector.
129 //return back, as no one is interested in notifications anymore.
130 return;
131 }
132 }
133
134 //Setting up next notification
135 Name nextNotification("/localhost/nfd/faces/events");
136 nextNotification.appendSegment(m_lastSequence + 1);
137
138 Interest interest(nextNotification);
139 interest.setInterestLifetime(time::seconds(60));
140
141 //todo: add logging support.
142 std::cout << "onNotification: Interest sent: " << interest << std::endl;
143
144 m_lastInterestId = m_face.expressInterest(interest,
145 bind(&FaceMonitor::onNotification, this, _2),
146 bind(&FaceMonitor::onTimeout, this));
147}
148
149}//namespace ndn
150