NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
notification-subscriber.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
48 #ifndef NDN_UTIL_NOTIFICATION_SUBSCRIBER_HPP
49 #define NDN_UTIL_NOTIFICATION_SUBSCRIBER_HPP
50 
51 #include "../face.hpp"
52 #include "signal.hpp"
53 #include "concepts.hpp"
54 #include <boost/concept_check.hpp>
55 
56 namespace ndn {
57 namespace util {
58 
63 template<typename Notification>
64 class NotificationSubscriber : noncopyable
65 {
66 public:
67  BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Notification>));
68  BOOST_CONCEPT_ASSERT((WireDecodable<Notification>));
69 
74  NotificationSubscriber(Face& face, const Name& prefix,
75  const time::milliseconds& interestLifetime = time::milliseconds(60000))
76  : m_face(face)
77  , m_prefix(prefix)
78  , m_isRunning(false)
79  , m_lastSequenceNo(std::numeric_limits<uint64_t>::max())
80  , m_lastInterestId(0)
81  , m_interestLifetime(interestLifetime)
82  {
83  }
84 
85  virtual
87  {
88  }
89 
94  time::milliseconds
96  {
97  return m_interestLifetime;
98  }
99 
100  bool
101  isRunning() const
102  {
103  return m_isRunning;
104  }
105 
110  void
112  {
113  if (m_isRunning) // already running
114  return;
115  m_isRunning = true;
116 
117  this->sendInitialInterest();
118  }
119 
122  void
124  {
125  if (!m_isRunning) // not running
126  return;
127  m_isRunning = false;
128 
129  if (m_lastInterestId != 0)
130  m_face.removePendingInterest(m_lastInterestId);
131  m_lastInterestId = 0;
132  }
133 
134 public: // subscriptions
139 
143 
147 
148 private:
149  void
150  sendInitialInterest()
151  {
152  if (this->shouldStop())
153  return;
154 
155  shared_ptr<Interest> interest = make_shared<Interest>(m_prefix);
156  interest->setMustBeFresh(true);
157  interest->setChildSelector(1);
158  interest->setInterestLifetime(getInterestLifetime());
159 
160  m_lastInterestId = m_face.expressInterest(*interest,
163  }
164 
165  void
166  sendNextInterest()
167  {
168  if (this->shouldStop())
169  return;
170 
171  BOOST_ASSERT(m_lastSequenceNo !=
172  std::numeric_limits<uint64_t>::max());// overflow or missing initial reply
173 
174  Name nextName = m_prefix;
175  nextName.appendSequenceNumber(m_lastSequenceNo + 1);
176 
177  shared_ptr<Interest> interest = make_shared<Interest>(nextName);
178  interest->setInterestLifetime(getInterestLifetime());
179 
180  m_lastInterestId = m_face.expressInterest(*interest,
183  }
184 
188  bool
189  shouldStop()
190  {
191  if (!m_isRunning)
192  return true;
193  if (onNotification.isEmpty()) {
194  this->stop();
195  return true;
196  }
197  return false;
198  }
199 
200  void
201  afterReceiveData(const Data& data)
202  {
203  if (this->shouldStop())
204  return;
205 
206  Notification notification;
207  try {
208  m_lastSequenceNo = data.getName().get(-1).toSequenceNumber();
209  notification.wireDecode(data.getContent().blockFromValue());
210  }
211  catch (tlv::Error&) {
212  this->onDecodeError(data);
213  this->sendInitialInterest();
214  return;
215  }
216 
217  this->onNotification(notification);
218 
219  this->sendNextInterest();
220  }
221 
222  void
223  afterTimeout()
224  {
225  if (this->shouldStop())
226  return;
227 
228  this->onTimeout();
229 
230  this->sendInitialInterest();
231  }
232 
233 private:
234  Face& m_face;
235  Name m_prefix;
236  bool m_isRunning;
237  uint64_t m_lastSequenceNo;
238  const PendingInterestId* m_lastInterestId;
239  time::milliseconds m_interestLifetime;
240 };
241 
242 } // namespace util
243 } // namespace ndn
244 
245 #endif // NDN_UTIL_NOTIFICATION_SUBSCRIBER_HPP
Copyright (c) 2011-2015 Regents of the University of California.
NotificationSubscriber(Face &face, const Name &prefix, const time::milliseconds &interestLifetime=time::milliseconds(60000))
construct a NotificationSubscriber
STL namespace.
time::milliseconds getInterestLifetime() const
void start()
start or resume receiving notifications
provides a lightweight signal / event system
signal::Signal< NotificationSubscriber > onTimeout
fires when no Notification is received within .getInterestLifetime period
signal::Signal< NotificationSubscriber, Notification > onNotification
fires when a Notification is received
Name & appendSequenceNumber(uint64_t seqNo)
Append sequence number using NDN naming conventions.
Definition: name.cpp:253
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:343
signal::Signal< NotificationSubscriber, Data > onDecodeError
fires when a Data packet in the Notification Stream cannot be decoded as Notification ...
Block blockFromValue() const
Definition: block.cpp:437
Abstraction to communicate with local or remote NDN forwarder.
Definition: face.hpp:100
provides a subscriber of Notification Stream
Name abstraction to represent an absolute name.
Definition: name.hpp:46
void stop()
stop receiving notifications
const PendingInterestId * expressInterest(const Interest &interest, const OnData &onData, const OnTimeout &onTimeout=OnTimeout())
Express Interest.
Definition: face.cpp:63
const Block & getContent() const
Get content Block.
Definition: data.cpp:230
uint64_t toSequenceNumber() const
Interpret as sequence number component using NDN naming conventions.
represents a Data packet
Definition: data.hpp:39
a concept check for TLV abstraction with .wireDecode method and constructible from Block ...
Definition: concepts.hpp:70
const Component & get(ssize_t i) const
Get the component at the given index.
Definition: name.hpp:419
void removePendingInterest(const PendingInterestId *pendingInterestId)
Cancel previously expressed Interest.
Definition: face.cpp:106
represents an error in TLV encoding or decoding
Definition: tlv.hpp:50